# Configurações

# Guia para Emissão e Configuração de Certificado SSL no DOX Portal

#### <span style="color: inherit;">Objetivo</span>

Este documento orienta clientes da Ema Sistemas na emissão e configuração de certificados SSL para uso em domínios próprios no DOX Portal.

<span style="white-space: pre-wrap;">A utilização do </span>**HTTPS**<span style="white-space: pre-wrap;"> (HTTP sobre SSL/TLS) garante uma camada adicional de segurança na comunicação entre o navegador e o servidor, protegendo os dados transmitidos por meio de criptografia.</span>

---

#### <span style="color: inherit;">✅ Etapas para Emissão e Configuração do Certificado SSL</span>

##### <span style="color: inherit;">1. Registrar um Domínio Próprio</span>

- <span style="white-space: pre-wrap;">Você deve possuir um </span>**domínio registrado em seu nome**<span style="white-space: pre-wrap;"> (ex: </span>`<span class="editor-theme-code">suaempresa.com.br</span>`)
- <span style="white-space: pre-wrap;">Este domínio servirá de base para criação do endereço de acesso ao DOX Portal (ex: </span>`<span class="editor-theme-code">dox.suaempresa.com.br</span>`)
- Se você não possui domínio, deve registrar através de:
    - **Registro.br**
    - Provedores de hospedagem (KingHost, GoDaddy, HostGator, etc.)

<span style="white-space: pre-wrap;">💡 </span>**Importante:**<span style="white-space: pre-wrap;"> A Ema </span>**não realiza**<span style="white-space: pre-wrap;"> o registro para os clientes, mas pode instruir como fazer. </span>**O registro de domínio é um serviço pago.**

##### <span style="color: inherit;">2. Hospedar o Domínio</span>

- <span style="white-space: pre-wrap;">Após o registro, o domínio deve estar vinculado a um </span>**serviço de hospedagem**<span style="white-space: pre-wrap;"> com suporte à emissão de certificados SSL</span>
- **Recomendação:**<span style="white-space: pre-wrap;"> Serviços como KingHost ou similares, que já oferecem emissão de certificados SSL compatíveis</span>

<span style="white-space: pre-wrap;">💰 </span>**A hospedagem do domínio também é um serviço pago.**

##### <span style="color: inherit;">3. Criar o Subdomínio e Emitir o Certificado SSL</span>

Com o domínio hospedado:

1. **Crie o subdomínio**<span style="white-space: pre-wrap;"> que será utilizado no acesso ao DOX Portal (ex: </span>`<span class="editor-theme-code">dox.suaempresa.com.br</span>`)
2. **Solicite no serviço de hospedagem**<span style="white-space: pre-wrap;"> a emissão do certificado SSL para este subdomínio, garantindo que o formato gerado seja compatível com o sistema da Ema: </span>**.PEM**<span style="white-space: pre-wrap;"> ou </span>**.CRT**
3. **Alternativa:**<span style="white-space: pre-wrap;"> Caso a hospedagem não ofereça emissão de certificado SSL, será necessário buscar uma </span>**certificadora terceirizada**<span style="white-space: pre-wrap;"> especializada. Esta alternativa exige atenção redobrada, pois envolve um processo mais técnico e pode demandar etapas adicionais de validação e configuração.</span>

<span style="white-space: pre-wrap;">⏱️ </span>**A emissão pode levar até 1 dia útil**, dependendo do provedor de hospedagem.

##### <span style="color: inherit;">4. Configurar o Certificado no Ema Configurador</span>

<span style="white-space: pre-wrap;">Com o certificado em mãos, siga os passos abaixo </span>**com apoio do Suporte da Ema**:

1. **Abra o Ema Configurador**<span style="white-space: pre-wrap;"> e edite o registro da conexão</span>
2. **Defina a porta principal como 443**<span style="white-space: pre-wrap;"> (HTTPS padrão). Portas alternativas também são permitidas, desde que especificadas corretamente no endereço de conexão</span>
3. **Marque a opção "Utiliza HTTPS"**
4. **Nos campos "Certificado" e "Arq. Senha"**<span style="white-space: pre-wrap;"> procure e informe o certificado no formato </span>**.PEM**<span style="white-space: pre-wrap;"> ou </span>**.CRT**
5. **Caso o cliente esteja executando o sistema anteriormente com conexão HTTP**<span style="white-space: pre-wrap;">, altere o caminho de conexão no seguinte arquivo, substituindo o protocolo de </span>`<span class="editor-theme-code">http</span>`<span style="white-space: pre-wrap;"> para </span>`<span class="editor-theme-code">https</span>`<span style="white-space: pre-wrap;"> e ajustando a porta.:</span>  
    ```
    C:\Ema Software\Contas ERP\Ema_Conexao_Servidor.ini
    ```

##### <span style="color: inherit;">5. Testar a Inicialização do Sistema com SSL</span>

<span style="white-space: pre-wrap;">Caso os microserviços do sistema não iniciem, execute o seguinte </span>**teste manual**:

1. **Abra o terminal do Windows**<span style="white-space: pre-wrap;"> (Prompt de Comando)</span>
2. **Execute:**  
    ```
    C:\Ema Software\Contas ERP\fabio.exe" -cfg fabio.properties
    ```
3. <span style="white-space: pre-wrap;">Este comando tenta inicializar o serviço com o certificado SSL configurado e mostrará </span>**mensagens de erro úteis para diagnóstico**

<span style="white-space: pre-wrap;">🔧 </span>**Se o sistema estiver online, pare os serviços pelo Ema\_Start antes de testar.**

---

#### <span style="color: inherit;">ℹ️ Informações Importantes</span>

#### <span style="color: inherit;">🌐 Clientes Cloud Server da Ema</span>

- <span style="white-space: pre-wrap;">O domínio fornecido para acesso ao cloud </span>**não pode ser usado**<span style="white-space: pre-wrap;"> para emissão de certificados SSL</span>
- <span style="white-space: pre-wrap;">O cliente </span>**deve possuir um domínio próprio**

#### <span style="color: inherit;">🆓 Opção Gratuita com Let's Encrypt</span>

- <span style="white-space: pre-wrap;">Também é possível emitir certificados </span>**gratuitamente**<span style="white-space: pre-wrap;"> com o Let's Encrypt</span>
- Esta opção exige:
    - **Conhecimento técnico em Linux**
    - <span style="white-space: pre-wrap;">Que o cliente </span>**renove o certificado a cada 90 dias**
- - <span style="white-space: pre-wrap;">Que o cliente </span>**renove o certificado a cada 90 dias**

---

#### <span style="color: inherit;">🔗 Documentação Relacionada</span>

<span style="white-space: pre-wrap;">Para mais informações sobre configuração de acesso externo, consulte também: </span>[Liberando o Acesso Externo ao DOX Portal](https://kb.emasistemas.com.br/books/configuracoes/page/liberando-o-acesso-externo-ao-dox-portal)

# Integração do Active Directory com Aplicações Ema

#### O que é Active Directory?

O Active Directory é uma implementação de serviço de diretório no protocolo LDAP que armazena informações sobre objetos em rede de computadores e disponibiliza essas informações a usuários e administradores desta rede.

#### Como Integrar com as Aplicações da Ema?

Primeiramente o ambiente do cliente precisar estar devidamente configurado com o AD DS (Active Directory Domain Service). Caso não esteja, não será possível utilizar o recurso. Caso queira configurar, deve entrar em contato com sua Equipe de TI para que seja realizada a configuração.

#### Habilitando o uso do AD nas aplicações

Para que o ERP/APS/DOX funcionem junto com o AD, precisamos habilitar o micro serviço Ema\_AD, sem ele não será possível.

Vamos em C:\\Ema Software\\Contas ERP\\ -&gt; aqui procuramos pelo Ema\_Configurador -&gt; vamos na aba serviços -&gt; habilitamos o micro serviço Ema\_AD -&gt; clicamos na opção salvar -&gt; e depois reiniciamos o serviço Ema start.

Após subir os serviços, devemos abrir o DOX estúdio, pois a configuração atualmente é feita única e exclusivamente pela aplicação.

configurações -&gt; parâmetros gerais -&gt; aba Active Directory, habilitar as seguintes opções:

- **Utilizar credenciais do AD**: Esse é o único parâmetro que deve estar sempre marcado, sem ele, a integração com o AD não funciona.
- **Utilizar login Automático**: Serve para que ao acessar quaisquer aplicações exceto, PDV e DOX portal, já faça o login direto, sem precisar informar usuário e senha.
- **Cadastrar automaticamente usuário/empregado no primeiro acesso**: Serve para ao acessar pela primeira vez o software, já seja criado um usuário com base nas credenciais do AD, usando como grupo de usuário o padrão definido no ultimo parâmetro.

# Liberando o Acesso Externo ao DOX Portal

Quer acessar o DOX Portal de qualquer lugar, com um endereço personalizado e seguro? Veja como liberar o acesso externo de forma simples e eficiente:

#### 🛠️ O que você vai precisar

- **Domínio próprio:**  
    <span style="white-space: pre-wrap;">Registrado no </span>[Registro.br](https://registro.br)<span style="white-space: pre-wrap;"> (ou outro provedor), com acesso ao painel de DNS para criar ou editar registros.</span>
- **Internet com IP público fixo:**  
    Necessário para garantir que seu endereço sempre aponte para o servidor correto.
    - Não sabe se sua conexão possui IP fixo? Consulte sua operadora de internet.
- **Endereço IP público em mãos:**  
    <span style="white-space: pre-wrap;">Para saber qual é o seu IP público, acesse: </span>[meuip.com.br](http://meuip.com.br).
- **Permissão de acesso ao roteador/firewall:**  
    Será necessário criar uma regra de redirecionamento (NAT/Port Forward) para liberar o acesso ao servidor do DOX Portal.
- **Acesso ao servidor onde o DOX Portal está instalado:**  
    Você vai precisar liberar portas no firewall do Windows e conferir as configurações do sistema.

#### 1️⃣ Crie o subdomínio para o DOX Portal

- <span style="white-space: pre-wrap;">No painel de DNS do seu domínio, crie um subdomínio (ex: </span>**dox.suaempresa.com.br**) e aponte para o IP público fixo da sua empresa. Usualmente, você deverá criar um registro de DNS do tipo A, vinculado ao seu endereço IP público.
- Confirme se está funcionando com o comando:
    - `<span class="editor-theme-code">ping dox.suaempresa.com.br</span>`

#### 2️⃣ Libere a porta de comunicação no seu firewall/gateway

- **Descubra a porta usada pelo DOX:**  
    <span style="white-space: pre-wrap;">Abra o </span>**Ema\_Configurador**<span style="white-space: pre-wrap;"> (</span>`<span class="editor-theme-code">C:\Ema Software\Contas ERP\Ema_Configurador.exe</span>`<span style="white-space: pre-wrap;">) e veja qual porta está configurada como </span>**Porta Principal**<span style="white-space: pre-wrap;"> (padrão é 80, mas pode ser outra).</span>
- **No firewall/roteador:**  
    <span style="white-space: pre-wrap;">Crie uma regra de </span>**NAT/Port Forward**<span style="white-space: pre-wrap;"> redirecionando a porta configurada para o IP interno do servidor DOX. Essa configuração é realizada de maneira diferente, de acordo com cada sistema ou equipamento.</span>
    - Exemplo:
        - **Porta externa:**<span style="white-space: pre-wrap;"> 80 (HTTP) ou a porta que estiver configurada</span>
        - **Destino interno:**<span style="white-space: pre-wrap;"> IP do servidor DOX (ex: 192.168.1.100)</span>
- **No Windows Firewall:**  
    Libere a mesma porta para entrada de conexões externas.

#### 3️⃣ Acesse o DOX Portal de fora da empresa

Agora você já pode acessar de qualquer lugar, usando:

- **Endereço padrão:**  
    [http://dox.suaempresa.com.br](#bkmrk-redirecionamento-aut)
- **Se usar porta diferente da 80:**  
    <span style="white-space: pre-wrap;">Inclua na URL (ex: </span>[http://dox.suaempresa.com.br:8080](#bkmrk-redirecionamento-aut))

#### 💡 Dicas extras

- **Redirecionamento automático:**<span style="white-space: pre-wrap;"> Se precisar, configure um redirecionamento de URL no seu serviço de hospedagem para facilitar o acesso sem precisar informar a porta, caso utilize uma porta alternativa a 80.</span>
- **Atualize a URL do portal no DOX:**  
    <span style="white-space: pre-wrap;">No sistema DOX, vá em </span>**Configurações → Parâmetros Gerais → Aba Geral → URL do portal**<span style="white-space: pre-wrap;"> e informe o endereço externo criado.</span>

# Pacote de funções - PostgreSQL

#### <span style="white-space: pre-wrap;">Criando o SCHEMA PKG\_EMA </span>

```sql
CREATE SCHEMA pkg_ema AUTHORIZATION postgres;
```

#### RETORNA COLUNA GRADE

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS character varying
 LANGUAGE plpgsql
AS $function$
  declare
   leitura varchar(4000);
  begin
   select
    resposta into leitura
   from public.crm_processo_grade_valor
   where idprocesso = xidprocesso
    and idformulario = xidformulario
    and idatividade = xidatividade
    and idgrade  = xidgrade
    and idvalor  = xidvalor
    and idrepeticao = (select max(idrepeticao)
          from crm_processo_grade_valor xx
          where xx.idatividade = crm_processo_grade_valor.idatividade
          and xx.idprocesso = crm_processo_grade_valor.idprocesso
          and xx.idformulario = crm_processo_grade_valor.idformulario);
  return(trim(leitura));
  end;
 $function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA COLUNA GRADE GLOB </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_clob(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_clob(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
  declare
   leitura text;
  begin
   select
    resposta into leitura
   from public.crm_processo_grade_valor
   where idprocesso = xidprocesso
    and idformulario = xidformulario
    and idatividade = xidatividade
    and idgrade  = xidgrade
    and idvalor  = xidvalor
    and idrepeticao = (select max(idrepeticao)
          from crm_processo_grade_valor xx
          where xx.idatividade = crm_processo_grade_valor.idatividade
          and xx.idprocesso = crm_processo_grade_valor.idprocesso
          and xx.idformulario = crm_processo_grade_valor.idformulario);
  return(trim(leitura));
  end;
 $function$
;
```

#### RETORNA COLUNA GRADE DATA

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_data(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_data(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS date
 LANGUAGE plpgsql
AS $function$
  declare
   leitura date;
  begin
   select respostadatahora into leitura
   from public.crm_processo_grade_valor
   where idprocesso = xidprocesso
    and idformulario= xidformulario
    and idatividade = xidatividade
    and idgrade  = xidgrade
    and idvalor  = xidvalor
    and idrepeticao = (select max(idrepeticao)
          from crm_processo_grade_valor xx
          where xx.idatividade = crm_processo_grade_valor.idatividade
          and xx.idprocesso = crm_processo_grade_valor.idprocesso
          and xx.idformulario = crm_processo_grade_valor.idformulario);
  return(leitura); --fazer o trim depois
  
  end;
 $function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA COLUNA GRADE DATAHORA </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_datahr(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_datahr(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS timestamp without time zone
 LANGUAGE plpgsql
AS $function$
  declare
   leitura timestamp;
  begin
   select respostadatahora into leitura
   from public.crm_processo_grade_valor
   where idprocesso = xidprocesso
    and idformulario= xidformulario
    and idatividade = xidatividade
    and idgrade  = xidgrade
    and idvalor  = xidvalor
    and idrepeticao = (select max(idrepeticao)
          from crm_processo_grade_valor xx
          where xx.idatividade = crm_processo_grade_valor.idatividade
          and xx.idprocesso = crm_processo_grade_valor.idprocesso
          and xx.idformulario = crm_processo_grade_valor.idformulario);
  return(leitura);
  
  end;
 $function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA COLUNA GRADE INTEIRO </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_int(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_int(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
 declare
  leitura int4;
 
  begin 
  /*leitura := 0 ;
  select (select to_number(decode(respostainteiro,'.',0,respostainteiro)) from dual)*/
 
  select respostainteiro into leitura
  from public.crm_processo_grade_valor
  where idprocesso = xidprocesso
  and idformulario = xidformulario
  and idatividade = xidatividade
  and idgrade = xidgrade
  and idvalor = xidvalor
  and idrepeticao = (select max(idrepeticao)
       from crm_processo_grade_valor xx
       where xx.idatividade = crm_processo_grade_valor.idatividade
       and xx.idprocesso = crm_processo_grade_valor.idprocesso);
 
  return(leitura);
 
  end;
 $function$
;
```

#### RETORNA COLUNA GRADE TEXTO

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_texto(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_texto(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS character varying
 LANGUAGE plpgsql
AS $function$
  declare
   leitura varchar(4000);
  begin
   select
    resposta into leitura
   from public.crm_processo_grade_valor
   where idprocesso = xidprocesso
    and idformulario = xidformulario
    and idatividade = xidatividade
    and idgrade  = xidgrade
    and idvalor  = xidvalor
    and idrepeticao = (select max(idrepeticao)
          from crm_processo_grade_valor xx
          where xx.idatividade = crm_processo_grade_valor.idatividade
          and xx.idprocesso = crm_processo_grade_valor.idprocesso
          and xx.idformulario = crm_processo_grade_valor.idformulario);
  return(trim(leitura));
  end;
 $function$
;
```

#### RETORNA COLUNA GRADE VALOR

```sql
-- DROP FUNCTION pkg_ema.retorna_coluna_grade_valor(int4, int4, int4, int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_coluna_grade_valor(xidprocesso integer, xidatividade integer, xidformulario integer, xidgrade integer, xidvalor integer)
 RETURNS numeric
 LANGUAGE plpgsql
AS $function$
  declare
   leitura numeric(15,2);
  begin  
   select respostavalor into leitura
   from public.crm_processo_grade_valor
   where idprocesso  = xidprocesso
    and idformulario  = xidformulario
    and idatividade  = xidatividade
    and idgrade   = xidgrade
    and idvalor   = xidvalor
    and idrepeticao  = (select max(idrepeticao)
           from crm_processo_grade_valor xx
           where xx.idatividade = crm_processo_grade_valor.idatividade
            and xx.idprocesso  = crm_processo_grade_valor.idprocesso);
   return(leitura);
  end;
 $function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA LISTA </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_lista(text, bpchar);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_lista(in_lista text, delimitador character)
 RETURNS TABLE(out_id integer, out_str text)
 LANGUAGE plpgsql
AS $function$
declare
  dados record;
begin
IN_LISTA = REPLACE(REPLACE(IN_LISTA,'(',''),')','');
   
   IF DELIMITADOR = '' OR DELIMITADOR IS NULL THEN DELIMITADOR = ','; END IF;
  IF IN_LISTA <> '.' and IN_LISTA is not null and IN_LISTA <> '' and (IN_LISTA not like '/%' and IN_LISTA not like '%/')  THEN   
  for dados in (select unnest(string_to_array(IN_LISTA, DELIMITADOR)) LISTA) 
  LOOP
  BEGIN
  OUT_ID  = cast(dados.lista as integer);
     OUT_STR = dados.lista;
  RETURN NEXT;
 
   EXCEPTION
WHEN OTHERS then
   OUT_ID = 0;
OUT_STR = dados.lista; 
    RETURN NEXT;
  END;
  END LOOP; 
  ELSE 
OUT_ID  = 0;
  OUT_STR = '0';
  RETURN NEXT;
END IF;
    
end;
$function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA VALOR VARIAVEL </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel(xidprocesso integer, xidvariavel integer)
 RETURNS character varying
 LANGUAGE plpgsql
AS $function$
  declare
  valor varchar(5000);
  begin
  select valoratual into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return valor;
  end;
$function$
;
```

#### RETORNA VALOR VARIAVEL BLOB

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_blob(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_blob(xidprocesso integer, xidvariavel integer)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
  declare
  valor text;
  begin
  select valorblob into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return trim(valor);
  end;
$function$
;
```

#### RETORNA VALOR VARIAVEL CLOB

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_clob(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_clob(xidprocesso integer, xidvariavel integer)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
  declare
  valor text;
  begin
  select valoratual into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return trim(valor);
  end;
$function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA VALOR VARIAVEL DATA </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_data(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_data(xidprocesso integer, xidvariavel integer)
 RETURNS date
 LANGUAGE plpgsql
AS $function$
  declare
   valor date;
  begin
  if (xidprocesso > 0 and xidvariavel > 0) then
  begin
  select case when valoratual <> '.' then to_date(valoratual,'dd/mm/yyyy HH24:MI')
   else to_date('01-01-1900','dd/mm/yyyy HH24:MI') end into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  end;
  else
  valor := to_date('01/01/1900','dd/mm/yyyy HH24:MI');
  end if;
  return valor;
  end;
$function$
;
```

#### RETORNA VALOR VARIAVEL DATAHORA

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_datahr(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_datahr(xidprocesso integer, xidvariavel integer)
 RETURNS timestamp without time zone
 LANGUAGE plpgsql
AS $function$
  declare
   valor timestamp;
  begin
  if (xidprocesso > 0 and xidvariavel > 0) then
  begin
  select case when valoratual <> '.' then to_timestamp(valoratual,'dd/mm/yyyy HH24:MI')
   else to_timestamp('01-01-1900','dd/mm/yyyy HH24:MI') end into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  end;
  else
  valor := to_timestamp('01/01/1900','dd/mm/yyyy HH24:MI');
  end if;
  return valor;
  end;
$function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA VALOR VARIAVEL INTEIRO </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_int(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_int(xidprocesso integer, xidvariavel integer)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
declare
 valor int4;
  begin
  select cast(case when valoratual = '.' then '0' else valoratual end as int4)
  into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return valor;
  end;
$function$
;
```

#### RETORNA VALOR VARIAVEL TEXTO

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_texto(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_texto(xidprocesso integer, xidvariavel integer)
 RETURNS character varying
 LANGUAGE plpgsql
AS $function$
  declare
  valor varchar(5000);
  begin
  select valoratual into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return valor;
  end;
$function$
;
```

#### <span style="white-space: pre-wrap;">RETORNA VALOR VARIAVEL VALOR </span>

```sql
-- DROP FUNCTION pkg_ema.retorna_valor_variavel_valor(int4, int4);

CREATE OR REPLACE FUNCTION pkg_ema.retorna_valor_variavel_valor(xidprocesso integer, xidvariavel integer)
 RETURNS numeric
 LANGUAGE plpgsql
AS $function$
  declare
   valor decimal(15,2) ;
  begin
  select replace(replace(case when valoratual = '.' then '0' else valoratual end, '.', ''), ',', '.')
  into valor
  from public.crm_processo_variavel
  where crm_processo_variavel.idprocesso = xidprocesso
  and crm_processo_variavel.idvariavel = xidvariavel ;
  return valor;
  end;
$function$
;
```

#### EXEMPLO RETORNO DE GRADE

```sql
SELECT PKG_EMA.RETORNA_COLUNA_GRADE_INT(X.IDPROCESSO, X.IDATIVIDADE, X.IDFORMULARIO, 1, X.IDVALOR) AS NOMECAMPO1,
       PKG_EMA.RETORNA_COLUNA_GRADE_INT(X.IDPROCESSO, X.IDATIVIDADE, X.IDFORMULARIO, 2, X.IDVALOR) AS NOMECAMPO2,
       PKG_EMA.RETORNA_COLUNA_GRADE_INT(X.IDPROCESSO, X.IDATIVIDADE, X.IDFORMULARIO, 3, X.IDVALOR) AS NOMECAMPO3,
       PKG_EMA.RETORNA_COLUNA_GRADE_VALOR(X.IDPROCESSO, X.IDATIVIDADE, X.IDFORMULARIO, 4, X.IDVALOR) AS NOMECAMPO4,
       0/*IDPROCESSO*/ AS IDPROCESSO
  FROM CRM_PROCESSO_GRADE_VALOR X
 WHERE IDPROCESSO = 0/*IDPROCESSO*/
   AND IDATIVIDADE = 3/*IDATIVIDAE*/
   AND IDFORMULARIO = 34/*IDFORMULARIO*/
   AND IDREPETICAO = (SELECT MAX(IDREPETICAO)
                        FROM CRM_PROCESSO_GRADE_VALOR
                       WHERE IDPROCESSO = X.IDPROCESSO
                         AND IDATIVIDADE = X.IDATIVIDADE)  
   AND IDGRADE = 1
```