📊 Painel de Checkout - Documentação Completa
1. Visão Geral
Módulo para monitoramento integrado de produção com:
- Comparativo entre previsto × realizado
- Cálculo automático de PPC (Planejamento e Programação de Controle)
- Visualização de ocorrências e métricas operacionais
- Filtros avançados por período, equipe e hierarquia
1.1 Visão Geral - Explicação Visual do Painel pelo figma:
🔗 Clique para visualizar o painel interativo no Figma
1.2 Calculos - Com Exemplos Práticos
1. PPC Semanal
Como funciona:
Conta todas as tarefas válidas de todas EQUIPES (por encarregados) durante o período de dias definido no filtro.
Verifica quantas dessas tarefas estão 100% concluídas (PPC_TAREFA == 100).
Fórmula:
- PPC Geral Semana = (Nº de tarefas 100% concluídas / Total de tarefas válidas) × 100 Exemplo:
- Período do filtro: 01/01/2025 até 07/01/2025
- Total de tarefas válidas: 200
- Tarefas 100% concluídas: 150
- Cálculo: (150/200) × 100 = 75%
2. PPC por Encarregado
Como funciona:
Conta todas as tarefas válidas de uma EQUIPE baseada no ENCARREGADO durante o período do filtro.
Fórmula:
- PPC Encarregado = (Nº de tarefas 100% concluídas pela equipe / Total de tarefas válidas da equipe) × 100
Exemplo:
- Período do filtro: 01/01/2025 até 07/01/2025
- Encarregado: João Silva
- Total de tarefas válidas: 20
- Tarefas 100% concluídas: 10
- Cálculo: (10/20) × 100 = 50%
3. PPC por Tarefa Individual
Como funciona:
Avaliação binária (100% ou 0%) de cada tarefa durante o período do filtro.
Critério:
- Se produção_atingida ≥ meta_prevista → 100% Senão → 0%
Exemplo:
- Tarefa: Instalação elétrica
- Meta prevista: 100 unidades
- Produção atingida: 98 unidades
- Resultado: 0% (não atingiu 100%)
4. % Produção do Dia
Como funciona:
Cálculo diário para um encarregado específico.
Fórmula:
- % Produção Dia = (Nº tarefas 100% concluídas no dia / Total tarefas válidas no dia) × 100
Exemplo:
- Data: 03/01/2025
- Encarregado: Maria Souza
- Total tarefas válidas: 8
- Tarefas concluídas: 6
- Cálculo: (6/8) × 100 = 75%
2. Configuração Inicial
2.1 Registro para ativação do painel no Menu
INSERT INTO nfs_core_menu
(SEQ_DB, EMPRESA, FILIAL, LOCAL, DESCRICAO, TYPE, ATIVO, FATHER, MENUORDER, URL, FILTER, ICON)
VALUES
(
10070,
9999,
9999,
9999,
'Painel de Checkout',
'LINK',
1,
9999,
1,
'checkoutPanel',
NULL,
'fa fa-tachometer'
);
3. Customização de Estrutura (Nos casos em que as tabelas app não existem no cliente que quer configurar o painel)
Contexto
O painel pressupõe o uso de tabelas padronizadas do sistema (
app_efetivo_funcionario
app_mo_oper
app_oper_grupo_metrica
app_efetivo_engenheiro
app_folha_tarefa
app_unidade_medida
app_mo_apt_motivo
app_tarefa
app_frente
app_motivo
app_folha_tarefa_n_frente
app_mo_boletim
).
Entretanto, para clientes que utilizam estrutura diferente dessa, é possível adaptar o módulo por meio de um parâmetro JSON configurável via entry point.
Registro de Tabelas e Colunas Ausentes ⚠️
O painel de checkout inclui um mecanismo automático de log que registra nos logs quais tabelas ou colunas necessárias não existem na estrutura do cliente.
3.1 SQL para ativação das customizações por parâmetros se necessário'
INSERT INTO nfs_entry_point (
SEQ_DB,
FILE_OR_DOMAIN,
`ACTION`,
XMOVA_INSTALLCODE,
XMOVA_INSTALLCODE_VERSION,
EMPRESA,
FILIAL,
`LOCAL`,
TABELA,
ENTRY_NUM,
CODE,
VERSION,
BUILD,
ATIVO,
CODETYPE,
FIELD,
DESCRIPTION,
INS_DH,
UPD_DH,
NFS_USER,
DB_USER
) VALUES (
765, -- [EXEMPLO] próximo SEQ_DB disponível na tabela
'PANEL',
'CHECKOUT_PANEL_CUSTOM',
NULL,
NULL,
9999,
9999,
9999,
'',
NULL,
'{
"panel_remap": {
},
"customize": {
}
}'-- [EXEMPLO] Configuração do JSON de customizações e remap
,
1,
NULL,
1,
'JSON',
NULL,
NULL,
'2022-09-23 22:46:08',
'2025-07-08 01:49:52',
'simova.admin@simova.com.br',
'exemplo@000.00.000.000'-- [EXEMPLO] vai salvar o usuário da alteração
);
3.2 Exemplos de configurações de JSON da coluna 'CODE' da tabela 'nfs_entry_point'
Configuração para substituir tabelas dentro da chave 'panel_remap':
{
"panel_remap": {
"tabela_original": "tabela_customizada",
"tabela.original_2": "tabela_customizada_2"
}
}
Configuração para substituição de Colunas:
{
"panel_remap": {
"tabela_original.coluna_original": "coluna_customizada",
"tabela_original.coluna_original_2": "coluna_customizada_2"
}
}
Traduzindo o valor padrão de cada título usado no customize para utilizar na configuração JSON:
Tabela Principal (ordem da esquerda para direita sem estar com as tarefas expandidas)
| Chave JSON | Posição | Exemplo de Valor Padrão |
|---|---|---|
table_column_title_1 | 1ª | "Gestor" |
table_column_title_2 | 2ª | "Supervisor" |
table_column_title_3 | 3ª | "Encarregado/Líder" |
table_column_ppc_week | 4ª | "PPC Semana" |
table_column_ppc_in_charge | 5ª | "PPC Encarregado" |
table_column_ppc_task | 6ª | "PPC Acumulado Tarefa" |
Subtabela (Detalhamento por Equipe)
| Chave JSON | Posição | Exemplo de Valor Padrão |
|---|---|---|
subtable_title_1 | 1ª | "Tarefa (CPO/FECHA)" |
subtable_title_2 | 2ª | "OBSERVAÇÃO (PLANEJAMENTO)" |
subtable_title_3 | 3ª | "UNIDADE MEDIDA" |
subtable_title_4 | 4ª | "SEMANA" |
subtable_title_5 | 5ª | "AVANÇO DE PRODUÇÃO" |
Seção de Ocorrências
| Chave JSON | Posição | Exemplo de Valor Padrão |
|---|---|---|
occurrence_title_1 | 1ª | "DATA OCORRENCIA" |
occurrence_title_2 | 2ª | "TAREFA (CPO / FECHA)" |
occurrence_title_3 | 3ª | "TIPO DE OCORRÊNCIA" |
occurrence_title_4 | 4ª | "DETALHE DA OCORRÊNCIA" |
occurrence_title_5 | 5ª | "CAUSA" |
occurrence_title_6 | 6ª | "SOLUCIONADO" |
Ex Customização de títulos de Colunas passando dentro da chave 'customize' se baseando nos valores acima
{
"customize": {
"table_column_title_1": "titulo_customizado",
"table_column_title_2": "titulo_customizado2",
"table_column_title_2": "titulo_customizado3",
"table_column_ppc_week": "titulo_customizado_ppc_week",
"table_column_ppc_in_charge": "titulo_customizado_ppc_in_charge",
"table_column_ppc_task": "titulo_customizado_ppc_task",
"subtable_title_1": "titulo_customizado_subtable",
"subtable_title_2": "titulo_customizado_subtable2",
"subtable_title_3": "titulo_customizado_subtable3",
"subtable_title_4": "titulo_customizado_subtable4",
"subtable_title_5": "titulo_customizado_subtable5",
"occurrence_title_1": "titulo_customizado_ocurrence1",
"occurrence_title_2": "titulo_customizado_ocurrence2",
"occurrence_title_3": "titulo_customizado_ocurrence3",
"occurrence_title_4": "titulo_customizado_ocurrence4",
"occurrence_title_5": "titulo_customizado_ocurrence5",
"occurrence_title_6": "titulo_customizado_ocurrence6"
}
}
Customização para ocultar colunas específicas seguindo a mesma lógica da customização de títulos porémm sem a possibilidade de ocultar as principais colunas subtabela, apenas da tabela principal, PPC e das ocorrencias, qualquer um desses, se estiver presente no JSON de configuração com o valor 1, ocultará a coluna referenciada
{
"customize": {
"table_column_hide_1": 1,
"table_column_hide_2": 1,
"table_column_hide_3": 1,
"table_column_ppc_hide": 1,
"occurrence_hide_1": 1,
"occurrence_hide_2": 1,
"occurrence_hide_3": 1,
"occurrence_hide_4": 1,
"occurrence_hide_5": 1,
"occurrence_hide_6": 1
}
}
Customização de cores à principio apenas da tabela e subtabela passando código hexadecimal da COR dentro do próprio 'customize'
{
"customize": {
"table_color": "#ffaa00",
"subtable_color": "#D35400"
}
}
Configuração de Sub-Tarefas (NFSCORE-1406)
O que são Sub-Tarefas?
As sub-tarefas permitem um detalhamento maior das atividades, onde tarefas principais podem ser divididas em componentes menores ao clicar na tarefa.
Como ativar/desativar:
A funcionalidade é controlada pelo parâmetro sub_task_setting no JSON de configuração dentro de 'customize':
{
"customize": {
"sub_task_setting": 1
}
}
3.3 Configuração de Larguras e Ordenação de Colunas (NFSCORE-1456)
Contexto
Foi implementado suporte para definição dinâmica de larguras de colunas e ordenamento configurável tanto na tabela principal, quanto nas subtabelas e subtarefas. Essa configuração é feita via parâmetros no JSON do entry point.
Parâmetros Disponíveis
Larguras (valores aceitam px, %, ou qualquer unidade CSS):
Tabela Principal
table_column_width_1table_column_width_2table_column_width_3
Subtabela (Equipe)
subtable_column_width_1subtable_column_width_2subtable_column_width_3subtable_column_width_4subtable_column_width_5
Subtarefas
subtabletask_column_width_1subtabletask_column_width_2subtabletask_column_width_3subtabletask_column_width_4subtabletask_column_width_5
Ordenação (string com índices separados por vírgula):
table_order→ define a ordem de exibição da tabela principalsubtable_order→ define a ordem de exibição das subtabelas e subtarefas
Exemplos de uso:
{
"customize": {
"table_column_width_1": "150px",
"table_column_width_2": "200px",
"table_column_width_3": "100px",
"table_order": "3,2,1",
"subtable_order": "3,5,1,2,4"
}
}
{
"customize": {
"table_column_width_1": "200px",
"table_column_width_2": "150px",
"table_column_width_3": "180px",
"table_order": "3,1,2",
"subtable_column_width_1": "250px",
"subtable_column_width_2": "200px",
"subtable_column_width_3": "150px",
"subtable_column_width_4": "180px",
"subtable_column_width_5": "220px",
"subtable_order": "5,1,2,3,4"
}
}
📐 Importância da Soma Total das Larguras
A soma das larguras precisa ser consistente com o layout esperado:
- Se a soma for menor, podem aparecer espaços em branco ou desalinhamentos.
- Se a soma for maior, pode ocorrer sobreposição de colunas ou problemas no scroll horizontal.
➡️ Esse controle garante que as colunas fixas permaneçam estáveis e alinhadas mesmo ao rolar o painel.
✅ Correções Incluídas
- Resolvido o problema ao abrir múltiplas subtarefas simultaneamente, onde antes as configurações de largura/ordem eram sobrescritas.
- Agora cada subtabela/subtarefa mantém sua configuração independente, garantindo previsibilidade e consistência.
4 🔧 EntryPoints para Customização de Cálculos PPC
📋 EntryPoints Disponíveis
| EntryPoint | Descrição | Fallback |
|---|---|---|
CHECKOUT_PPC_TAREFA | Calcula PPC individual de cada tarefa | |
CHECKOUT_PPC_ENCARREGADO | Calcula PPC consolidado por encarregado | |
CHECKOUT_PPC_GERAL | Calcula PPC geral do sistema |
🔧 Configuração de exemplo no Banco (alguns VALUES são exemplos, não considerar ao fazer o INSERT)
INSERT INTO nfs_entry_point
(SEQ_DB, FILE_OR_DOMAIN, ACTION, XMOVA_INSTALLCODE, XMOVA_INSTALLCODE_VERSION,
EMPRESA, FILIAL, LOCAL, TABELA, ENTRY_NUM, CODE, VERSION, BUILD,
ATIVO, CODETYPE, FIELD, DESCRIPTION, INS_DH, UPD_DH, NFS_USER, DB_USER)
VALUES
(NEXTVAL('seq_nfs_entry_point'), 'SYSTEM', 'CHECKOUT_PPC', NULL, NULL,
9999, 9999, 9999, 'CHECKOUT_PANEL', 1,
"
if (isset($this->param['tarefa'])) {
// PPC_TAREFA
// NOVA REGRA: Quando Real TOTAL >= Planejado TOTAL → 100%, senão → 0%
$tarefa = $this->param['tarefa'];
$totalReal = 0;
$totalPlanejado = 0;
foreach ($tarefa as $day => $data) {
if (!is_array($data)) continue;
$planejado = $data['TOTAL_METRICA_PREVISTA'] ?? 0;
$real = $data['TOTAL_METRICA_PRODUZIDA'] ?? 0;
$totalPlanejado += $planejado;
$totalReal += $real;
}
// NOVA REGRA: Se Real TOTAL >= Planejado TOTAL → 100%, senão → 0%
$ppc = ($totalPlanejado > 0 && $totalReal >= $totalPlanejado) ? 100 : 0;
$this->outputValues = $ppc;
} elseif (isset($this->param['tarefas'])) {
// PPC_ENCARREGADO
// NOVA REGRA: Soma o percentual de cada linha de tarefa e divide pela quantidade de tarefas
$tarefas = $this->param['tarefas'];
$somaPpcTarefas = 0;
$quantidadeTarefas = 0;
foreach ($tarefas as $tarefa) {
$totalReal = 0;
$totalPlanejado = 0;
foreach ($tarefa as $day => $data) {
if (!is_array($data)) continue;
$planejado = $data['TOTAL_METRICA_PREVISTA'] ?? 0;
$real = $data['TOTAL_METRICA_PRODUZIDA'] ?? 0;
$totalPlanejado += $planejado;
$totalReal += $real;
}
// NOVA REGRA: Tarefa binária - 100% ou 0% (não mais por dias)
if ($totalPlanejado > 0) {
$ppcTarefa = ($totalReal >= $totalPlanejado) ? 100 : 0;
$somaPpcTarefas += $ppcTarefa;
$quantidadeTarefas++;
}
}
// Média dos PPCs das tarefas
$ppc = ($quantidadeTarefas > 0) ? ($somaPpcTarefas / $quantidadeTarefas) : 0;
$this->outputValues = min(round($ppc, 2), 100);
} elseif (isset($this->param['data'])) {
// PPC_GERAL/SEMANA
// NOVA REGRA: Soma o percentual de cada PPC Encarregado e divide pela quantidade de encarregados
$data = $this->param['data'];
$somaPpcEncarregados = 0;
$quantidadeEncarregados = 0;
foreach ($data as $encarregadoData) {
if (!isset($encarregadoData['TAREFAS_AGREGADAS'])) continue;
$somaPpcTarefasEncarregado = 0;
$quantidadeTarefasEncarregado = 0;
foreach ($encarregadoData['TAREFAS_AGREGADAS'] as $task) {
if (!is_array($task)) continue;
$totalReal = 0;
$totalPlanejado = 0;
foreach ($task as $day => $t) {
if (is_array($t)) {
$planejado = $t['TOTAL_METRICA_PREVISTA'] ?? 0;
$real = $t['TOTAL_METRICA_PRODUZIDA'] ?? 0;
$totalPlanejado += $planejado;
$totalReal += $real;
}
}
// NOVA REGRA: Tarefa binária - 100% ou 0%
if ($totalPlanejado > 0) {
$ppcTarefa = ($totalReal >= $totalPlanejado) ? 100 : 0;
$somaPpcTarefasEncarregado += $ppcTarefa;
$quantidadeTarefasEncarregado++;
}
}
// Calcula PPC do encarregado (média das tarefas)
if ($quantidadeTarefasEncarregado > 0) {
$ppcEncarregado = $somaPpcTarefasEncarregado / $quantidadeTarefasEncarregado;
$somaPpcEncarregados += $ppcEncarregado;
$quantidadeEncarregados++;
}
}
// Média dos PPCs dos encarregados
$ppc = ($quantidadeEncarregados > 0) ? ($somaPpcEncarregados / $quantidadeEncarregados) : 0;
$this->outputValues = min(round($ppc, 2), 100);
}
",
1, 0, 'PHP', NULL, 'Cálculo de PPC unificado',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'SISTEMA', CURRENT_USER);