Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configurações

Vídeos

Parte 1 | Parte 2 | Parte 3 |

Exibir registros Inativos em Relatórios e Gráficos

Para a exibição de dados de registros inativos onde se faz necessário, foi criada a chave inativos nas configurações de QueryBuilder. Assim, caso seja necessários selecionar também os registros inativos em determinados processos, basta adicionar essa chave com valor true; o valor padrão é ausente/false (somente registros onde ATIVO é igual a 1).

{
	"locais":{
		"dump": "",
		"inativos": true,
		"main": true,
		"select":[
			"sum(if(e.FLAG_PROPRIO=1, 1, 0)) FIBRIA",
			"sum(if(e.FLAG_PROPRIO=0, 1, 0)) PROVEDOR",
			"(select l.NOME from nfs_org_local l where e.LOCAL = l.SEQ_DB)'FILIAL'"
		],
		"from":"equipamento e",
		"group_by":[
			"e.LOCAL"
		]
	},
  ...
}

Obter Data Atual

Para obter a data atual de acordo com o fuso horário da filial, para isso foi criado o seguinte parâmetro:

:NFS_NOW (Necessário os dois pontos)

Obter EMPRESA e/ou FILIAL e/ou LOCAL

Para obter a data atual de acordo com o empresa da filial, para isso foi criado o seguinte parâmetro:

:NFS_EMPRESA (Necessário os dois pontos)

Para obter a data atual de acordo com o filial da filial, para isso foi criado o seguinte parâmetro:

:NFS_FILIAL (Necessário os dois pontos)

Para obter a data atual de acordo com o local da filial, para isso foi criado o seguinte parâmetro:

:NFS_LOCAL (Necessário os dois pontos)

Como usar

Eles devem ser usados no select e/ou where como no exemplo abaixo para o :NFS_NOW:

"secondary_table": {
      "select": [
        "1 as funcionarioApontando",
        "BOLETIM.FIM_DH FIM_DH",
        "BOLETIM.FUNCIONARIO_SEQ_DB",
        "BOLETIM.SEQ_DB BOLETIM_SEQ_DB",
        ":NFS_NOW AGORA",
        "(select sec_to_time(sum(time_to_sec(TIMEDIFF(if(a.FIM_DH is null,:NFS_NOW,a.FIM_DH),a.INI_DH)))) from app_apontamento a inner join app_boletim b on b.SEQ_DB = a.SEQ_DB_DEVICE_MASTER_SEQ_DB where a.TIPO_APONTAMENTO = 1 and b.FIM_DH is null and a.SEQ_DB_DEVICE_MASTER_SEQ_DB = BOLETIM.SEQ_DB) as WORKING"
      ],
      "from": "BOLETIM",
  ...
 }

Como é possível observar foi criar valor com o apelido AGORA onde é usado o parâmetro :NFS_NOW, também é usando para calcular as horas trabalhadas onde verifica se a data final é nulla e caso verdadeiro usa a data atual.

Obter Imagem da tabela NFS_UPLOAD

Para obter o conteúdo da imagem e usa-lo em algum relatório, é necessário utilizar o seguinte parâmetro:

~upload:fk_foto:apelido
  • ~upload: é uma constante, funciona com uma palavra chave.
  • fk_foto: Aqui é o nome da coluna que é usada no query builder que faz relacionamento com a imagem salva na NFS_UPLOAD.
  • apelido: É o apelido atribuido a coluna, onde será usada no relatório.

O retorno é a coluna CONTEUDO da tabela NFS_UPLOAD.

Exemplo:

{
  "os_list": {
    "select": [
      "distinct os.SEQ_DB SEQ_DB",
      "os.CODIGO CODIGO",
      "os.FILIAL FILIAL",
      "st.DESCRICAO STATUS_OS",
      "os.EQUIPAMENTO_SEQ_DB",
      "osf.FUNCIONARIO_SEQ_DB",
      "f.NOME",
      "f.CRACHA",
      "~upload:f.foto_seq_db:foto"
    ],
    "from": "os os",
    "with": ["cliente:descricao,codigo", "funcionario:nome"],
    "left_join": [
      ["os", "os_tecnico", "osf", "osf.OS_SEQ_DB = os.SEQ_DB"],
      ["osf", "funcionario", "f", "f.SEQ_DB = osf.FUNCIONARIO_SEQ_DB"],
      [
        "os",
        "apontamento",
        "a",
        "a.OS_SEQ_DB = os.SEQ_DB AND osf.FUNCIONARIO_SEQ_DB = a.FUNCIONARIO_SEQ_DB"
      ],
      ["os", "cliente", "c", "c.SEQ_DB  = os.CLIENTE_SEQ_DB"],
      ["osf", "status_os", "st", "osf.status_os_seq_db  = st.SEQ_DB"]
    ],
    "where": ["os.SEQ_DB in (:os)", "osf.FUNCIONARIO_SEQ_DB in (:funcionario)"]
  }
}

No caso acima na tabela de FUNCIONARIO tem a coluna FOTO_SEQ_DB que é uma fk para a tabela NFS_UPLOAD, e o apelido foto que o seu valor será a imagem em base64.

Opção HAVING

Para utilizar a opção having do sql basta colocar a seguinte opção no json:

"having" : ["condicao_1" , "condicao_2"]

Opção Union

Para utilizar o Union no Nfs Query Builder é bem simples, basicamento é a união de duas nfs query builder com apenas um resultado, a sua estrutura é

{
  "union": {
    "query_1": {
      // select, from ,where...
    },
    "query_2": {
      // select, from ,where...
    }
  }
}

Para entrar na condição é necessário ter primeiro a chave union e dentro dela uma ou mais nfs query builder, no caso acima tem a query_1 e a query_2.

ATENÇÃO É importante dizer que o resultado das duas consultas devem ser iguais.

Opção group_result_by e group_result_by_unique

A funcionalidade group_result_by recebe um único parâmetro e deve ser o nome do campo que deseja com chave do array resultante. Veja abaixo um exemplo (use o recurso no admin/testCode do NFS para ver o resultado):

$json = '{"eqp_apontamentos":{
		"select":["a.SEQ_DB","a.EQP_SEQ_DB"],
		"from":"eqp_apt a",
		"where":["DATE(a.INI_DH) = DATE(NOW())"],
		"order_by": [["a.SEQ_DB", "ASC"]]
		}}';
$array = json_decode($json, true);
var_dump(\core\NFSQueryBuilder::getQuery($array));

Nesse caso acima serão listados todos os apontamentos do dia com SEQ_DB do apontamento e SEQ_DB do EQP e CHAVE do array é um sequencial que começa em 0.

Se você precisar agrupar o resultado do array pelo SEQ_DB equipamento (para usar num código ou twig):

$json = '{"eqp_apontamentos":{
		"select":["a.SEQ_DB","a.EQP_SEQ_DB"],
		"from":"eqp_apt a",
		"where":["DATE(a.INI_DH) = DATE(NOW())"],
    "order_by": [["a.SEQ_DB", "ASC"]],
    "group_result_by": "EQP_SEQ_DB"
		}}';
$array = json_decode($json, true);
var_dump(\core\NFSQueryBuilder::getQuery($array));

Pronto, veja que o próprio CORE criou um array ordenado.

ATENÇÃO Alguns códigos/entryPoint/Report estão fazendo uso de campo no group_result_by que NÃO ESTÃO NOS CAMPOS DO SELECT. E também não deve ser usado o alias da tabela, exemplo de uso errado: a.EQP_SEQ_DB. ATENÇÃO, o campo do group_result_by deve ser único, portanto, use um ALIAS se for preciso. Exemplo abaixo:

$json = '{"eqp_apontamentos":{
		"select":["a.SEQ_DB","a.EQP_SEQ_DB GROUP_EQP"],
		"from":"eqp_apt a",
		"where":["DATE(a.INI_DH) = DATE(NOW())"],
    "order_by": [["a.SEQ_DB", "ASC"]],
    "group_result_by": "GROUP_EQP"
		}}';
$array = json_decode($json, true);
var_dump(\core\NFSQueryBuilder::getQuery($array));

SOBRE O group_result_by_unique

Utilize group_result_by_unique no lugar de group_result_by quando o campo que será usado como índice é o próprio SEQ_DB da tabela. Esse uso é muito comum para recuperar um cadastro e usar para impressão dos dados. Veja o exemplo abaixo:

Com group_result_by você precisaria colocar equipamento[1][0].CODIGO e usando group_result_by_unique você só precisa do primeiro índice equipamento[1].CODIGO

Caso esse agrupamento seja usado em um campo com muitos registros (Exemplo: EQP_CLASSE_SEQ_DB) somente UM registro será retornado em cada cahve do array.

$json = '{	"equipamentos": {
		"select": ["eqp.SEQ_DB","eqp.EQP_CLASSE_SEQ_DB",
			"eqp.CODIGO",
			"eqp.DESCRICAO"
		],
		"from": "eqp eqp",
		"group_result_by_unique": "SEQ_DB",
		"order_by": [
			["eqp.SEQ_DB", "ASC"]
		]
	}
}';
$array = json_decode($json, true);
var_dump(\core\NFSQueryBuilder::getQuery($array));

Exemplo - Porcentagem Total de Atividades Produtivas e o Detalhado por Atividades Improdutivas

No exemplo abaixo o resulta da primeira query é a porcentagem de todas as atividades produtivas e a segunda a porcentagem por atividades improdutivas, passando um período como parâmetro.

{
  "union": {
    "produtiva": {
      "select": [
        "concat ('produtiva') name",
        "sum(a.INI_FIM_DIFF_SEC) y",
        "concat('HORAS: ',(round((select sum(a2.INI_FIM_DIFF_SEC) total from app_apontamento_maquina a2 inner join app_grupo_atividade g2 on g2.SEQ_DB = a2.GRUPO_ATIVIDADE_SEQ_DB inner join app_atividade ati2 on a2.ATIVIDADE_SEQ_DB = ati2.SEQ_DB where g2.ativo = 1 and g2.DELETED = 0 and a2.ATIVO = 1 and a2.DELETED = 0 and a2.filial = a.filial and g2.filial = g.filial and date(a2.INI_DH) >= min(date(a.INI_DH)) and date(a2.INI_DH) <= max(date(a.INI_DH)))/ 3600, 2))) legend"
      ],
      "from": "apontamento_maquina a",
      "inner_join": [
        ["a", "grupo_atividade", "g", "g.SEQ_DB = a.GRUPO_ATIVIDADE_SEQ_DB"],
        ["a", "atividade", "ati", "a.ATIVIDADE_SEQ_DB = ati.SEQ_DB"]
      ],
      "where": [
        "date(a.INI_DH) >= date_format(STR_TO_DATE(:ini, '%d/%m/%Y'), '%Y-%m-%d')",
        "date(a.INI_DH) <= date_format(STR_TO_DATE(:fim, '%d/%m/%Y'), '%Y-%m-%d')",
        "ati.FLAG_PRODUTIVA = 1"
      ],
      "group_by": ["name"]
    },
    "paradas": {
      "select": [
        "concat(g.DESCRICAO,'::', ati.DESCRICAO) name",
        "sum(a.INI_FIM_DIFF_SEC) y",
        "concat('HORAS: ',(round((select sum(a2.INI_FIM_DIFF_SEC) total from app_apontamento_maquina a2 inner join app_grupo_atividade g2 on g2.SEQ_DB = a2.GRUPO_ATIVIDADE_SEQ_DB inner join app_atividade ati2 on a2.ATIVIDADE_SEQ_DB = ati2.SEQ_DB where g2.ativo = 1 and g2.DELETED = 0 and a2.ATIVO = 1 and a2.DELETED = 0 and a2.filial = a.filial and g2.filial = g.filial and date(a2.INI_DH) >= min(date(a.INI_DH)) and date(a2.INI_DH) <= max(date(a.INI_DH)))/ 3600, 2))) legend"
      ],
      "from": "apontamento_maquina a",
      "inner_join": [
        ["a", "grupo_atividade", "g", "g.SEQ_DB = a.GRUPO_ATIVIDADE_SEQ_DB"],
        ["a", "atividade", "ati", "a.ATIVIDADE_SEQ_DB = ati.SEQ_DB"]
      ],
      "where": [
        "date(a.INI_DH) >= date_format(STR_TO_DATE(:ini, '%d/%m/%Y'), '%Y-%m-%d')",
        "date(a.INI_DH) <= date_format(STR_TO_DATE(:fim, '%d/%m/%Y'), '%Y-%m-%d')",
        "ati.FLAG_PRODUTIVA = 0"
      ],
      "group_by": ["a.GRUPO_ATIVIDADE_SEQ_DB", "a.ATIVIDADE_SEQ_DB, a.FILIAL"]
    }
  }
}

É possível ver o resultado acessando como simova.admin@simova.com.br na base da SuzanoSA de homologação, clicando no menu do Usuário entre na opção Admin Console e na opção NFS ENTRY POINT clique no item Test Code, ao abrir apague os exemplos que são carregados, por fim copie e cole o código abaixo e aberte o botão Testar.

$json = '{"union":{"produtiva":{"select":["concat (\'produtiva\') name","sum(a.INI_FIM_DIFF_SEC) y","concat(\'HORAS: \',(round((select sum(a2.INI_FIM_DIFF_SEC) total from app_apontamento_maquina a2 inner join app_grupo_atividade g2 on g2.SEQ_DB = a2.GRUPO_ATIVIDADE_SEQ_DB inner join app_atividade ati2 on a2.ATIVIDADE_SEQ_DB = ati2.SEQ_DB where g2.ativo = 1 and g2.DELETED = 0 and a2.ATIVO = 1 and a2.DELETED = 0 and a2.filial = a.filial and g2.filial = g.filial and date(a2.INI_DH) >= min(date(a.INI_DH)) and date(a2.INI_DH) <= max(date(a.INI_DH)))/ 3600, 2))) legend"],"from":"apontamento_maquina a","inner_join":[["a","grupo_atividade","g","g.SEQ_DB = a.GRUPO_ATIVIDADE_SEQ_DB"],["a","atividade","ati","a.ATIVIDADE_SEQ_DB = ati.SEQ_DB"]],"where":["date(a.INI_DH) >= date_format(STR_TO_DATE(\'01/02/2019\', \'%d/%m/%Y\'), \'%Y-%m-%d\')","date(a.INI_DH) <= date_format(STR_TO_DATE(\'28/02/2019\', \'%d/%m/%Y\'), \'%Y-%m-%d\')","ati.FLAG_PRODUTIVA = 1"],"group_by":["name"]},"paradas":{"select":["concat(g.DESCRICAO,\'::\', ati.DESCRICAO) name","sum(a.INI_FIM_DIFF_SEC) y","concat(\'HORAS: \',(round((select sum(a2.INI_FIM_DIFF_SEC) total from app_apontamento_maquina a2 inner join app_grupo_atividade g2 on g2.SEQ_DB = a2.GRUPO_ATIVIDADE_SEQ_DB inner join app_atividade ati2 on a2.ATIVIDADE_SEQ_DB = ati2.SEQ_DB where g2.ativo = 1 and g2.DELETED = 0 and a2.ATIVO = 1 and a2.DELETED = 0 and a2.filial = a.filial and g2.filial = g.filial and date(a2.INI_DH) >= min(date(a.INI_DH)) and date(a2.INI_DH) <= max(date(a.INI_DH)))/ 3600, 2))) legend"],"from":"apontamento_maquina a","inner_join":[["a","grupo_atividade","g","g.SEQ_DB = a.GRUPO_ATIVIDADE_SEQ_DB"],["a","atividade","ati","a.ATIVIDADE_SEQ_DB = ati.SEQ_DB"]],"where":["date(a.INI_DH) >= date_format(STR_TO_DATE(\'01/02/2019\', \'%d/%m/%Y\'), \'%Y-%m-%d\')","date(a.INI_DH) <= date_format(STR_TO_DATE(\'28/02/2019\', \'%d/%m/%Y\'), \'%Y-%m-%d\')","ati.FLAG_PRODUTIVA = 0"],"group_by":["a.GRUPO_ATIVIDADE_SEQ_DB","a.ATIVIDADE_SEQ_DB, a.FILIAL"]}}}';

$array = json_decode($json, true);
var_dump(\core\NFSQueryBuilder::getQuery($array));

Opção dump

Os valores possíveis são:

  • sql Vai apresentar na tela a query montada e os parâmetros disponíveis para uso.
  • result Retorna os dados DESSA query em formato JSON (antes do método de tratamento de dados)
  • resultData Retorna os dados DESSA query em formato JSON (após método de tratamento de dados)
  • resultAll Retorna os dados de TODAS as queries em formato JSON.
"dump" : "sql|result|resultData|resultAll"

Opção DEBUG_INFO

Os dados disponíveis são:

$_SESSION['DEBUG_MODE'] = 1;
print_r($_SESSION['DEBUG_CONFIG']);
print_r($_SESSION['DEBUG_PARAMS']);
print_r($_SESSION['DEBUG_SQL']);

Legendas

Hoje é possível todas as cores e descrições das legendas serem dinânmicas, isso ajuda em situações onde quer o painel não deve ser o padrão, por exemplo por padrão boletim fechado é sempre preto, mas há situação onde o cliente quer configurar um cor caso o último boletim fechado já faz mais de 3 dias, então é possível fazer esse cálculo na quer e definir uma cor.

Legenda - Main Table

Legenda - Secondary Table

Legenda - Additional Tables