Histórico da Página
...
Este monitor não realiza o cálculo da qualidade em tempo real, ele apenas apresenta os valores gerados pela opção Gerar Indicadores do SFCA008 - Metas de Produção.
É possível configurar a Geração dos Indicadores para que seja processado em modo Schedule - Gerar Indicadores em Schedule - SFCA008.
02.
...
TIPOS DISPONÍVEIS
- Gráfico (velocímetro, barra, coluna)
...
Quando selecionado o tipo Barra ou Coluna são apresentados os percentuais dos indicadores Qualidade Real e Qualidade.
03.
...
FILTROS
Os filtros para definição do escopo a ser monitorado são os seguintes:
*Filtro obrigatório
| Filtro | Descrição |
|---|---|
| Filial* | Seleção simples da filial a ser monitorada, a partir da lista das filiais disponíveis. |
| Máquina* | Seleção simples da máquina a ser monitorada, a partir da informação da máquina ou da pesquisa dentre as máquinas disponíveis para a filial. |
| Semáforo* | Dois valores numéricos, separados por ponto e vírgula (;), que indicam os níveis de Urgência e Atenção. Desta forma, com o objetivo de mostrar o nível da utilização da máquina. Quando o número for:
Observação: O semáforo é um filtro obrigatório, porém, somente será utilizado se o tipo do Gráfico selecionado for Velocímetro. Caso for informado outro tipo do Gráfico (barra ou coluna), deve ser informado qualquer valor no Semáforo, conforme as regras, mas não será utilizada essa informação. |
| Meta Produzida* | Seleção simples da meta a ser monitorada, a partir da informação da meta ou da pesquisa dentre a metas disponíveis para a filial. |
Data Atual | Indica se o monitor irá utilizar a data atual ou não.
|
Data de referência | Indica qual data irá utilizar para o monitoramento da máquina. |
| Hora de referência | Indica qual hora irá utilizar para o monitoramento da máquina. |
...
As Tags auxiliam na identificação do escopo de um monitor, sem necessidade de editá-los.
| Tag | Ícone | Descrição |
|---|---|---|
| Data de Referência | Data de Referência da geração do indicador pela opção Gerar Indicadores do SFCA008 - Metas de Produção. | |
| Hora de Referência | Hora de Referência da geração do indicador pela opção Gerar Indicadores do SFCA008 - Metas de Produção. | |
| Máquina | Código da Máquina que está sendo monitorada. | |
| Meta Produzida | Código da Meta que está sendo monitorada. |
05. DETALHES
Apresenta as informações utilizadas para o cálculo da Qualidade Real e da Qualidade.
...
07. EXEMPLOS
- Visão geral do monitor:
Gráfico do tipo Velocímetro
Gráfico do tipo Colunas
Gráfico do tipo Barras
- Tags auxiliares:
- Detalhes:
08. CÓDIGO FONTE
| Dica |
|---|
Segue abaixo o código fonte da classe responsável pelos dados deste monitor. Utilize este código como base para criar seus monitores exclusivos, alterando o nome da classe e adaptando à sua regra de negócio. |
| Bloco de código | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
#INCLUDE "PROTHEUS.CH"
#INCLUDE "PCPMONITOR.CH"
#INCLUDE "PCPMONITORDEF.CH"
/*/{Protheus.doc} QualidadeSFC
Classe para mostrar o indicador de Qualidade do modulo do SFC
@type Class
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@return Nil
/*/
Class QualidadeSFC FROM LongNameClass
Static Method BuscaDados(oFiltros, cTipo, cSubTipo)
Static Method BuscaDetalhes(oFiltros, nPagina)
Static Method CargaMonitor()
Static Method ValidaPropriedades(oFiltros)
EndClass
/*/{Protheus.doc} CargaMonitor
Realiza a carga do Monitor padrão na base de dados
@type Method
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@return lRet, logico, Indica se conseguiu realizar a carga
/*/
Method CargaMonitor() Class QualidadeSFC
Local aCategr := {}
Local aDetalhes := {}
Local aTags := {}
Local lRet := .T.
Local nIndTag := 0
Local oCarga := PCPMonitorCarga():New()
Local oGauge := PCPMonitorGauge():New()
Local oPrmAdc := JsonObject():New()
Local oSeries := JsonObject():New()
If !PCPMonitorCarga():monitorAtualizado("QualidadeSFC")
PCPMonitorUtils():AdicionaTagMonitor(aTags,@nIndTag,"po-icon-calendar","1622/0406/20232025")
PCPMonitorUtils():AdicionaTagMonitor(aTags,@nIndTag,"an an-clock","15:25:10")
PCPMonitorUtils():AdicionaTagMonitor(aTags,@nIndTag,"po-icon-bar-code","SFC-MAQ")
PCPMonitorUtils():AdicionaTagMonitor(aTags,@nIndTag,"po-icon-bar-code","SFC-META")
oGauge:SetValue(55)
oGauge:SetValueStyle("color",COR_AMARELO_QUEIMADO)
oGauge:SetValueStyle("font-weight","bold")
oGauge:SetLabel(STR0348) //"% Qualidade"
oGauge:SetLabelStyle("font-weight","bold")
oGauge:SetThreshold("0",COR_VERMELHO_FORTE)
oGauge:SetThreshold("40",COR_AMARELO_QUEIMADO)
oGauge:SetThreshold("75",COR_VERDE_FORTE)
oGauge:SetMarker("0")
oGauge:SetMarker("40")
oGauge:SetMarker("75")
oGauge:SetMarker("100")
oCarga:setaTitulo(STR0349) //"Qualidade SFC"
oCarga:setaObjetivo(STR0350) //"Apresenta a porcentagem de Qualidade da máquina, utilizando o conceito de semáforo para indicar o nível de atenção ou urgência."
oCarga:setaAgrupador("SFC")
oCarga:setaFuncaoNegocio("QualidadeSFC")
oCarga:setaTiposPermitidos("chart")
oCarga:setaTiposGraficoPermitidos("gauge;column;bar")
oCarga:setaTipoPadrao("chart")
oCarga:setaTipoGraficoPadrao("gauge")
oCarga:setaTipoDetalhe("detalhe")
oCarga:setaExemploJsonGrafico(oSeries, aTags, aDetalhes,aCategr,"gauge",oGauge:GetJsonObject())
oCarga:setaPropriedadeFilial("QUALI_FILIAL")
oCarga:setaPropriedade("QUALI_SEMAFORO", STR0314, STR0315,1,10,0,"po-sm-12 po-md-6 po-lg-6 po-xl-6",/*oEstilos*/,/*cIcone*/,/*oPrmAdc*/)// "Urgente;Atenção;Urgente" "Semáforo"
oCarga:setaPropriedadeLookupTabela("QUALI_MAQUINA", STR0316, .F., "CY5CYB", "CY5CYB_CDMQ", "CYB_DSMQ") //"Máquina"
oCarga:setaPropriedadeLookupTabela("QUALI_METAPROD", STR0317, .F., "CY5CYU", "CY5CYU_CDMEPO", "CYU_DSME") //"Meta Produzida"
oCarga:setaPropriedade("QUALI_DATAREF", "", STR0318, 3,8,0, "po-sm-12 po-md-6 po-lg-6 po-xl-6",/*oEstilos*/,/*cIcone*/,/*oPrmAdc*/) //"Data de Referência"
oCarga:setaPropriedade("QUALI_HORAREF", STR0319, STR0320,1,8,0, "po-sm-12 po-md-6 po-lg-6 po-xl-6",/*oEstilos*/,/*cIcone*/,/*oPrmAdc*/) //"Hora de Referência"
oPrmAdc["QUALI_DATAATUAL"] := JsonObject():New()
oPrmAdc["QUALI_DATAATUAL"]["opcoes"] := STR0321 + ":" + "S" + ";" + STR0322 + ":" + "N" // "Sim" "Não"
oCarga:setaPropriedade("QUALI_DATAATUAL", "N", STR0323, 4,/*cTamanho*/,/*cDecimal*/, "po-sm-12 po-md-6 po-lg-6 po-xl-6",/*oEstilos*/,/*cIcone*/,oPrmAdc["QUALI_DATAATUAL"]) //"Data Atual"
If !oCarga:gravaMonitorPropriedades()
lRet := .F.
EndIf
oCarga:Destroy()
EndIf
FreeObj(oGauge)
FreeObj(oSeries)
FreeObj(oPrmAdc)
Return lRet
/*/{Protheus.doc} BuscaDados
Responsável por realizar a busca dos dados que serão exibidos no monitor
@type Method
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@param oFiltros , objeto Json, Contém as propriedades do monitor usadas para filtrar a query de busca
@param cTipo , caracter , Tipo chart
@param cSubTipo , caracter , Tipo de grafico gauge, column, bar
@return cJsonDados, caracter , Retorna um novo Json em formato texto, pronto para conversão e exibição no front
/*/
Method BuscaDados(oFiltros, cTipo, cSubTipo) Class QualidadeSFC
Local aSemaforo := StrTokArr(Replace(oFiltros["QUALI_SEMAFORO"],",","."),";")
Local cAliasDH := ""
Local cAliasInd := ""
Local cCodMaq := oFiltros["QUALI_MAQUINA"]
Local cCodMeta := oFiltros["QUALI_METAPROD"]
Local cJsonDados := ""
Local cLabel := ""
Local cQueryDH := ""
Local cQueryInd := ""
Local dDataRef := Replace(oFiltros["QUALI_DATAREF"],"-","")
Local hHoraRef := oFiltros["QUALI_HORAREF"]
Local nDataatual := oFiltros["QUALI_DATAATUAL"]
Local nPos := 0
Local nValor1 := 0
Local nValor2 := 0
Local oExecDH := Nil
Local oExecInd := Nil
Local oJsonRet := JsonObject():New()
oFiltros["QUALI_FILIAL"] := PadR(oFiltros["QUALI_FILIAL"], FWSizeFilial())
//Propriedades que devem ser retornadas para monitores do tipo gráfico
oJsonRet["corTitulo" ] := "black"
oJsonRet["alturaMinimaWidget"] := "350px"
oJsonRet["alturaMaximaWidget"] := "550px"
oJsonRet["series" ] := {}
oJsonRet["categorias" ] := {}
oJsonRet["tags" ] := {}
If nDataatual == "S"
dDataRef := DATE()
hHoraRef := Time()
Else
dDataRef := SToD(dDataRef)
EndIf
// Obtendo a data e hora de referência mais próximas da indicada durante a seleção
cQueryDH := " SELECT CZ4.CZ4_DTRE, "
cQueryDH += " CZ4.CZ4_HRRE "
cQueryDH += " FROM " + RetSQLName('CZ4') + " CZ4 "
cQueryDH += " WHERE CZ4.CZ4_FILIAL = ? "
cQueryDH += " AND CZ4.CZ4_IDMEPO IN (SELECT CY5.CY5_IDMEPO "
cQueryDH += " FROM " + RetSQLName('CY5') + " CY5 "
cQueryDH += " WHERE CY5.CY5_FILIAL = CZ4.CZ4_FILIAL "
cQueryDH += " AND CY5.CY5_CDMEPO = ? "
cQueryDH += " AND CY5.CY5_CDMQ = ? "
cQueryDH += " AND CY5.D_E_L_E_T_ = ' ') "
cQueryDH += " AND (( CZ4.CZ4_DTRE = ? "
cQueryDH += " AND CZ4.CZ4_HRRE <= ?) "
cQueryDH += " OR CZ4.CZ4_DTRE <= ?) "
cQueryDH += " AND CZ4.D_E_L_E_T_ = ' ' "
cQueryDH += " ORDER BY CZ4.CZ4_DTRE DESC, "
cQueryDH += " CZ4.CZ4_HRRE DESC "
oExecDH := FwExecStatement():New(cQueryDH)
oExecDH:SetString(1, xFilial("CZ4",oFiltros["QUALI_FILIAL"]))
oExecDH:SetString(2, cCodMeta)
oExecDH:SetString(3, cCodMaq)
oExecDH:SetDate(4, dDataRef)
oExecDH:SetString(5, hHoraRef)
oExecDH:SetDate(6, dDataRef)
cAliasDH := oExecDH:OpenAlias()
If (cAliasDH)->(!EOF())
dDataRef := SToD((cAliasDH)->CZ4_DTRE)
hHoraRef := (cAliasDH)->CZ4_HRRE
EndIf
//Query com os filtros para buscar as informações e apresentar no monitor
cQueryInd += " SELECT CZ4.CZ4_VLQLRY VLQLRY, "
cQueryInd += " CZ4.CZ4_VLQL VLQL "
cQueryInd += " FROM " + RetSqlName("CZ4") + " CZ4 "
cQueryInd += " INNER JOIN " + RetSqlName("CY5") + " CY5 "
cQueryInd += " ON CY5.CY5_FILIAL = ? "
cQueryInd += " AND CY5.CY5_IDMEPO = CZ4.CZ4_IDMEPO "
cQueryInd += " AND CY5.D_E_L_E_T_ = ' ' "
cQueryInd += " WHERE CZ4.CZ4_FILIAL = ? "
cQueryInd += " AND CZ4.CZ4_CDMQ = ? "
cQueryInd += " AND CZ4.CZ4_DTRE = ? "
cQueryInd += " AND CZ4.CZ4_HRRE = ? "
cQueryInd += " AND CY5.CY5_CDMEPO = ? "
cQueryInd += " AND CZ4.D_E_L_E_T_ = ' ' "
oExecInd := FwExecStatement():New(cQueryInd)
oExecInd:SetString(1, xFilial("CY5",oFiltros["QUALI_FILIAL"]))
oExecInd:SetString(2, xFilial("CZ4",oFiltros["QUALI_FILIAL"]))
oExecInd:SetString(3, cCodMaq)
oExecInd:SetDate(4, dDataRef)
oExecInd:SetString(5, hHoraRef)
oExecInd:SetString(6, cCodMeta)
cAliasInd := oExecInd:OpenAlias()
nValor1 := 0
nValor2 := 0
If (cAliasInd)->(!Eof())
nValor1 := Round((cAliasInd)->VLQLRY,2)
nValor2 := Round((cAliasInd)->VLQL,2)
cLabel := STR0348 //"% Qualidade"
ElseEndIf
nValor1 :If cSubTipo == 0
nValor2 := 0
EndIf
If cSubTipo == "gauge"
"gauge"
montaGraf(oJsonRet, cLabel, nValor1, aSemaforo)
Else
aAdd(oJsonRet["series"], JsonObject():New())
oJsonRet["series"][1]["color" ] := COR_VERDE
oJsonRet["series"][1]["data" ] := {nValor1}
oJsonRet["series"][1]["tooltip"] := ""
oJsonRet["series"][1]["label" ] := STR0351 //"% Qualidade Real"
aAdd(oJsonRet["series"], JsonObject():New())
oJsonRet["series"][2]["color" ] := COR_AZUL
oJsonRet["series"][2]["data" ] := {nValor2}
oJsonRet["series"][2]["tooltip"] := ""
oJsonRet["series"][2]["label" ] := STR0348 //"% Qualidade"
EndIf
//Adiciona tags ao monitor
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPos,"po-icon-calendar",cValToCharPCPConvDat(DTos(dDataRef), 4))
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPos,"an an-clock",hHoraRef)
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPos,"po-icon-bar-code",cCodMaq)
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPos,"po-icon-bar-code",cCodMeta)
cJsonDados := oJsonRet:toJson()
FwFreeArray(aSemaforo)
FreeObj(oJsonRet)
FreeObj(oExecDH)
FreeObj(oExecInd)
Return cJsonDados
/*/{Protheus.doc} BuscaDetalhes
Responsável por realizar a busca dos dados que serão exibidos no detalhamento do monitor
@type Method
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@param oFiltros , objeto Json , Contém as propriedades do monitor usadas para filtrar a query de busca
@param nPagina , numerico , Número da página desejada para busca
@return cJsonDados, caracter , Retorna um novo Json em formato texto, pronto para conversão e exibição no front
/*/
Method BuscaDetalhes(oFiltros, nPagina) Class QualidadeSFC
Local cAliasDH := ""
Local cAliasItem := ""
Local cCodMaq := oFiltros["QUALI_MAQUINA"]
Local cCodMeta := oFiltros["QUALI_METAPROD"]
Local cJsonDados := ""
Local cQueryDH := ""
Local cQueryItem := ""
Local dDataRef := Replace(oFiltros["QUALI_DATAREF"],"-","")
Local hHoraRef := oFiltros["QUALI_HORAREF"]
Local nDataatual := oFiltros["QUALI_DATAATUAL"]
Local nIndTag := 0
Local nPos := 0
Local oDadosnStart := JsonObject():New()1
Local oExecDH nTamPagina := Nil20
Local oExecItemoDados := JsonObject():New()
Local oExecDH := Nil
Local oExecItem := Nil
Default nPagina := 1
oFiltros["QUALI_FILIAL"] := PadR(oFiltros["QUALI_FILIAL"], FWSizeFilial())
oDados["items" ] := {}
oDados["columns" ] := montaColun()
oDados["canExportCSV"] := .T.
oDados["tags" ] := {}
If nDataatual == "S"
dDataRef = DATE()
hHoraRef = Time()
Else
dDataRef := SToD(dDataRef)
EndIf
cQueryDH := " SELECT CZ4.CZ4_DTRE, "
cQueryDH += " CZ4.CZ4_HRRE "
cQueryDH += " FROM " + RetSQLName("CZ4") + " CZ4 "
cQueryDH += " WHERE CZ4.CZ4_FILIAL = ? "
cQueryDH += " AND CZ4.CZ4_IDMEPO IN (SELECT CY5.CY5_IDMEPO
cQueryDH += " FROM " + RetSQLName("CY5") + " CY5 "
cQueryDH += " WHERE CY5.CY5_FILIAL = CZ4.CZ4_FILIAL "
cQueryDH += " AND CY5.CY5_CDMEPO = ? "
cQueryDH += " AND CY5.CY5_CDMQ = ? "
cQueryDH += " AND CY5.D_E_L_E_T_ = ' ') "
cQueryDH += " AND (( CZ4.CZ4_DTRE = ? "
cQueryDH += " AND CZ4.CZ4_HRRE <= ? ) "
cQueryDH += " OR CZ4.CZ4_DTRE <= ? ) "
cQueryDH += " AND CZ4.D_E_L_E_T_ = ' ' "
cQueryDH += " ORDER BY CZ4.CZ4_DTRE DESC, "
cQueryDH += " CZ4.CZ4_HRRE DESC "
oExecDH := FwExecStatement():New(cQueryDH)
oExecDH:SetString(1, xFilial("CZ4",oFiltros["QUALI_FILIAL"]))
oExecDH:SetString(2, cCodMeta)
oExecDH:SetString(3, cCodMaq)
oExecDH:SetDate(4, dDataRef)
oExecDH:SetString(5, hHoraRef)
oExecDH:SetDate(6, dDataRef)
cAliasDH := oExecDH:OpenAlias()
If (cAliasDH)->(!EOF())
dDataRef := SToD((cAliasDH)->CZ4_DTRE)
hHoraRef := (cAliasDH)->CZ4_HRRE
EndIf
cQueryItem += " SELECT CZ4CZ5.CZ5_FILIALCDAC, "
cQueryItem += " CZ4_DTRESum(CZ5.CZ5_HRTEAT) AS CZ5_HRTEAT, "
cQueryItem += " CZ4_HRRE Sum(CZ5.CZ5_QTRPPL) AS CZ5_QTRPPL, "
cQueryItem += " CZ4_IDMEPOSum(CZ5.CZ5_QTRP) AS CZ5_QTRP, "
cQueryItem += " CZ4_CDESSum(CZ5.CZ5_QTRF) AS CZ5_QTRF, "
cQueryItem += " CZ4_CDARPO, Sum(CZ5.CZ5_QTRT) AS CZ5_QTRT "
cQueryItem += " FROM " + RetSqlName("CZ5") + " CZ4_CDCETR,CZ5 "
cQueryItem += " INNER JOIN " + RetSqlName("CZ4") + " CZ4_CDMQ, "
cQueryItem += " ON CZ4.CZ4_FILIAL " CZ4_VLQLRY,= ? "
cQueryItem += " AND CZ4.CZ4_DTRE " CZ4_VLQL, = CZ5.CZ5_DTRE "
cQueryItem += " AND CZ4.CZ4_HRRE " CZ4_QTRPRY, = CZ5.CZ5_HRRE "
cQueryItem += " AND CZ4.CZ4_IDMEPO " CZ4_QTRFRY,= CZ5.CZ5_IDMEPO "
cQueryItem += " AND CZ4.D_E_L_E_T_ = " CZ4_QTRTRY,' ' "
cQueryItem += " INNER JOIN " + RetSqlName("CY5") + " CZ4_VLTK,CY5 "
cQueryItem += " ON CY5.CY5_FILIAL "= CY5_CDMEPO? "
cQueryItem += " FROM " + RetSqlName("CZ4") + " CZ4AND CY5.CY5_IDMEPO = CZ4.CZ4_IDMEPO "
cQueryItem += " INNER JOIN " +AND RetSqlName("CY5") + " CY5CY5.D_E_L_E_T_ = ' ' "
cQueryItem += " ONWHERE CY5CZ5.CY5CZ5_FILIAL = ? "
cQueryItem += " AND CY5CZ5.CY5CZ5_IDMEPOCDMQ = CZ4.CZ4_IDMEPO? "
cQueryItem += " AND CY5CZ4.D_E_L_E_T_CZ4_DTRE = '? ' "
cQueryItem += " WHEREAND CZ4.CZ4_FILIALHRRE = ? "
cQueryItem += " " AND CZ4CY5.CZ4CY5_CDMQCDMEPO = ? "
cQueryItem += " " AND CZ4(CZ5.CZ4CZ5_DTRE TPMV = ?'4' "
cQueryItem += " AND" OR CZ4CZ5.CZ4CZ5_HRRETPMV = ?'1') "
cQueryItem += " " AND CY5.CY5_CDMEPO = ?CZ5.D_E_L_E_T_ = ' ' "
cQueryItem += " GROUP ANDBY CZ4.D_E_L_E_T_ = ' ' "
oExecItem := FwExecStatement(CZ4_DTRE, "
cQueryItem += " CZ4.CZ4_HRRE, "
cQueryItem += " CZ5.CZ5_CDAC "
cQueryItem += " ORDER BY CZ5.CZ5_CDAC "
oExecItem := FwExecStatement():New(cQueryItem)
oExecItem:SetString(1, xFilial("CY5CZ4",oFiltros["QUALI_FILIAL"]))
oExecItem:SetString(2, xFilial("CZ4CY5",oFiltros["QUALI_FILIAL"]))
oExecItem:SetString(3, xFilial("CZ5",oFiltros["QUALI_FILIAL"]))
oExecItem:SetString(4, cCodMaq)
oExecItem:SetDate(45, dDataRef)
oExecItem:SetString(56, hHoraRef)
oExecItem:SetString(67, cCodMeta)
cAliasItem := oExecItem:OpenAlias()
While (cAliasItem)->(!Eof())If nPagina > 1
aAdd(nStart := ( (nPagina-1) * nTamPagina )
If nStart > 0
(cAliasItem)->(DbSkip(nStart))
EndIf
EndIf
While (cAliasItem)->(!Eof())
aAdd(oDados["items"], JsonObject():New())
nPos++
oDados["items"][nPos]["CZ4CZ5_FILIALCDAC" ] := (cAliasItem)->CZ4>CZ5_FILIALCDAC
oDados["items"][nPos]["CZ4CZ5_DTREHRTEAT" ] := SToD((cAliasItem)->CZ4>CZ5_DTRE)HRTEAT
oDados["items"][nPos]["CZ4CZ5_HRREQTRPPL" ] := Round((cAliasItem)->CZ4_HRRE>CZ5_QTRPPL, 2)
oDados["items"][nPos]["CZ4CZ5_IDMEPOQTRP" ] := Round((cAliasItem)->CZ4_IDMEPO>CZ5_QTRP, 2)
oDados["items"][nPos]["CZ4CZ5_CDESQTRF" ] := Round((cAliasItem)->CZ4_CDES>CZ5_QTRF, 2)
oDados["items"][nPos]["CZ4CZ5_CDARPOQTRT" ] := Round((cAliasItem)->CZ4_CDARPO>CZ5_QTRT, 2)
oDados["items"][nPos]["CZ4_CDCETR"] := (cAliasItem)->CZ4_CDCETR>(dbSkip())
oDados["items"][nPos]["CZ4_CDMQ" ] := (cAliasItem)->CZ4_CDMQ
oDados["items"][nPos]["CZ4_VLQLRY"] := Round((cAliasItem)->CZ4_VLQLRY, 2)
oDados["items"][nPos]["CZ4_VLQL" ] := Round((cAliasItem)->CZ4_VLQL, 2)
oDados["items"][nPos]["CZ4_QTRPRY"] := (cAliasItem)->CZ4_QTRPRY
oDados["items"][nPos]["CZ4_QTRFRYIf nPos >= nTamPagina
Exit
EndIf
EndDo
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"po-icon-calendar",PCPConvDat(DToS(dDataRef), 4))
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"an an-clock",hHoraRef)
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"po-icon-bar-code",cCodMaq)
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"po-icon-bar-code",cCodMeta)
oDados["hasNext"] := (cAliasItem)->CZ4_QTRFRY
oDados["items"][nPos]["CZ4_QTRTRY"]>(!Eof())
(cAliasItem)->(dbCloseArea())
cJsonDados := (cAliasItem)->CZ4_QTRTRY
oDados["items"][nPos]["CZ4_VLTK" ] := (cAliasItem)->CZ4_VLTK
oDados:ToJson()
FreeObj(oExecDH)
FreeObj(oExecItem)
Return cJsonDados
/*/{Protheus.doc} ValidaPropriedades
Valida os dados informados nas propriedades do Monitor
@type Method
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@param oFiltros, objeto json, Objeto json com os filtros para a consulta dos dados
@return aRetorno, array , oDados["items"][nPos]["CY5_CDMEPO"] := (cAliasItem)->CY5_CDMEPO
(cAliasItem)->(dbSkip())
EndDo1] logico - indica se os dados são válidos [2] caracter - mensagem de erro
/*/
Method ValidaPropriedades(oFiltros) Class QualidadeSFC
Local aRetorno := {.T., ""}
Local aSemaforo := {}
Local nX := 0
PCPMonitorUtils():AdicionaTagMonitorValidaPropriedadeFilial(oDadosoFiltros["tagsQUALI_FILIAL"],@nIndTag,"po-icon-calendar",IIF(nDataatual == "S", DToS(dDataRef), dDataRef))
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"po-icon-bar-code",cCodMaq)
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nIndTag,"po-icon-bar-code",cCodMeta)
oDados["hasNext"] := (cAliasItem)->(!Eof())
(cAliasItem)->(dbCloseArea())
cJsonDados := oDados:ToJson()
FreeObj(oExecDH)
FreeObj(oExecItem)
Return cJsonDados
/*/{Protheus.doc} ValidaPropriedades
Valida os dados informados nas propriedades do Monitor
@type Method
@author
@since
@version
@param oFiltros, objeto json, Objeto json com os filtros para a consulta dos dados
@return aRetorno, array , [1] logico - indica se os dados são válidos [2] caracter - mensagem de erro
/*/
Method ValidaPropriedades(oFiltros) Class QualidadeSFC
Local aRetorno := {.T., ""}
Local aSemaforo := {}
Local nX := 0
PCPMonitorUtils():ValidaPropriedadeFilial(oFiltros["QUALI_FILIAL"],aRetorno)
If aRetorno[1] .AndaRetorno)
If aRetorno[1] .And. Empty(oFiltros["QUALI_MAQUINA"])
aRetorno[1] := .F.
aRetorno[2] := STR0325 //"A Máquina deve ser informada."
EndIf
If aRetorno[1] .And. Empty(oFiltros["QUALI_METAPROD"])
aRetorno[1] := .F.
aRetorno[2] := STR0326 //"A meta deve ser informada."
EndIf
If aRetorno[1] .And. oFiltros["QUALI_DATAATUAL"] == "N"
If Empty(oFiltros["QUALI_DATAREF"]) .Or. Empty(oFiltros["QUALI_FILIALHORAREF"])
aRetorno[1] := .F.
aRetorno[2] := STR0324STR0327 //"A FilialData devee Hora deve ser informada."
EndIf
EndIf
If aRetorno[1]
If !oFiltros:HasProperty("QUALI_SEMAFORO") .AndOr. Empty(oFiltros["QUALI_MAQUINASEMAFORO"])
aRetorno[1] := .F.
aRetorno[2] := STR0325 //"A Máquina deve ser informada."
EndIf
If aRetorno[1] .And.Nil .Or. Empty(oFiltros["QUALI_METAPRODSEMAFORO"])
aRetorno[1] := .F.
aRetorno[2] := STR0326STR0328 //"A metaO campo 'Semáforo' deve ser informada."
EndIf
If aRetorno[1] .And. oFiltros["QUALI_DATAATUAL"] == "N"
If Empty preenchido com 2 valores separados por ponto e vírgula (ex.: '10;100') que indicam Urgência e Atenção, respectivamente"
Else
aSemaforo := STRTOKARR(Replace(oFiltros["QUALI_DATAREFSEMAFORO"]) .Or. Empty(oFiltros["QUALI_HORAREF"],",","."),";")
aRetornoIf Len(aSemaforo) <> 2
aRetorno[1] := .F.
aRetorno[2] := STR0327STR0328 //"AO Datacampo e'Semáforo' Hora deve ser informada."
EndIf
EndIf
If aRetorno[1]
If !oFiltros:HasProperty("QUALI_SEMAFORO") .Or. oFiltros["QUALI_SEMAFORO"] == Nil .Or. Empty(oFiltros["QUALI_SEMAFORO"])
preenchido com 2 valores separados por ponto e vírgula (ex.: '10;100') que indicam Urgência e Atenção, respectivamente"
Else
For nX := 1 To 2
If Empty(aSemaforo[nX])
aRetorno[1] := .F.
aRetorno[2] := STR0328 //"O campo 'Semáforo' deve ser preenchido com 2 valores separados por ponto e vírgula (ex.: '10;100') que indicam AtençãoUrgência e UrgênciaAtenção, respectivamente"
Else Exit
EndIf
aSemaforo := STRTOKARR(Replace(oFiltros["QUALI_SEMAFORO"],",","."),";")
Next nX
If LenVal(aSemaforo[1]) <> 2
>= Val(aSemaforo[2])
aRetorno[1] := .F.
aRetorno[2] := STR0328STR0329 //"ONo campo 'Semáforo', deveo serprimeiro preenchidovalor, comreferente 2ao valores separados por ponto e vírgula (ex.: '10;100') que indicam Atenção e Urgência, respectivamente"
Else
For nX := 1 To 2
If Empty(aSemaforo[nX])
aRetorno[1] := .F.
aRetorno[2] := STR0328 //"O campo 'Semáforo' deve ser preenchido com 2 valores separados por ponto e vírgula (ex.: '10;100') que indicam Atenção e Urgência, respectivamente"
Exit
EndIf
Next nX
If Val(aSemaforo[1]) >= Val(aSemaforo[2])
aRetorno[1] := .F.
aRetorno[2] := STR0329 //"No campo 'Semáforo', o primeiro valor, referente ao status 'Atenção', deve ser menor que o segundo, que representa 'Urgência'"
EndIf
EndIf
EndIf
EndIf
FwFreeArray(aSemaforo)
Return aRetorno
/*/{Protheus.doc} montaColun
Realiza a criação de objeto Json que define as colunas utilizadas na grid de detalhamento do monitor
@type Static Function
@author
@since
@version
@return aColumns, array objetos, Contém as definições das colunas da grid do monitor
/*/
Static Function montaColun()
Local aColunas := {}
Local nIndCol := 0
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_FILIAL",STR0330,"string" ,.T.) //"Filial"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_DTRE" ,STR0331,"string" ,.T.) //"Data Referência"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_HRRE" ,STR0332,"string" ,.T.) //"Hora Referência"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_IDMEPO",STR0333,"string" ,.T.) //"ID Meta"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CY5_CDMEPO",STR0334,"string" ,.T.) //"Meta"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_CDMQ" ,STR0335,"string" ,.T.) //"Máquina"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_VLQL" ,STR0348,"string" ,.T.) //"% Qualidade"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_VLQLRY",STR0351,"string" ,.T.) //"% Qualidade Real"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4_CDES" ,STR0337,"string" ,.T.) //"Estabelecimento"
status 'Urgência', deve ser menor que o segundo, que representa 'Atenção'"
EndIf
EndIf
EndIf
EndIf
FwFreeArray(aSemaforo)
Return aRetorno
/*/{Protheus.doc} montaColun
Realiza a criação de objeto Json que define as colunas utilizadas na grid de detalhamento do monitor
@type Static Function
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@return aColumns, array objetos, Contém as definições das colunas da grid do monitor
/*/
Static Function montaColun()
Local aColunas := {}
Local nIndCol := 0
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_CDARPOCDAC" ,STR0338STR0374,"string" ,.T.) //"Área de ProduçãoItem"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_CDCETRHRTEAT",STR0339STR0366,"string" ,.T.) //"CentroTempo de TrabalhoReal"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_QTRPRYQTRPPL",STR0371STR0367,"string" ,.T.) //"Quant. AprovadaProjetada"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_QTRFRYQTRP" ,STR0372STR0368,"string" ,.T.) //"Quant. RefugadaReal"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_QTRTRYQTRF" ,STR0373STR0375,"string" ,.T.) //"Quant.Refugo RetrabalhadaReal"
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndCol,"CZ4CZ5_VLTKQTRT" ,STR0346STR0376,"numberstring" ,.T.) //"TaktRetrabalho TimeReal"
Return aColunas
/*/{Protheus.doc} montaGraf
Monta objeto json com os dados para mostrar o gauge
@type Static Function
@author breno.ferreira
@since 08/10/2025
@version P12.1.2410
@param oJsonRet , objeto json, Objeto json que receberá os dados do gauge
@param cLabel , character , Label para apresentar no gráfico
@param nValor , numerico , Número de lotes retornado da consulta
@param aSemaforo , array , Array com os números do semáforo
@return Nil
/*/
Static Function montaGraf(oJsonRet,cLabel,nValor,aSemaforo)
Local cValorFim := ""
Local cValSemaf1 := aSemaforo[1]
Local cValSemaf2 := aSemaforo[2]
Local nValorFim := 0
Local nValSemaf1 := Val(cValSemaf1)
Local nValSemaf2 := Val(cValSemaf2)
Local oGauge := PCPMonitorGauge():New()
If nValor > nValSemaf2
nValorFim := nValor + (nValSemaf2 - nValSemaf1)
Else
nValorFim := nValSemaf2 + (nValSemaf2 - nValSemaf1)
EndIf
cValorFim := cValToChar(nValorFim)
//Especifica as propriedades do gráfico tipo velocímetro
oGauge:SetMaxValue(nValorFim)
oGauge:SetValue(nValor)
oGauge:SetValueStyle("color",IIF(nValor < nValSemaf1,"rgb(245,0,49)",IIF(nValor < nValSemaf2,"rgb(255,240,10)","rgb(38,186,65)")))
oGauge:SetValueStyle("font-weight","bold")
oGauge:SetLabel(cLabel)
oGauge:SetLabelStyle("font-weight","bold")
oGauge:SetThreshold("0","rgb(245,0,49)")
oGauge:SetThreshold(cValSemaf1,"rgb(255,240,10)")
oGauge:SetThreshold(cValSemaf2,"rgb(38,186,65)")
If Val(cValSemaf1) > 0
oGauge:SetMarker("0")
Endif
oGauge:SetMarker(cValSemaf1)
oGauge:SetMarker(cValSemaf2)
oGauge:SetMarker(cValorFim)
//Atribui o objeto json do velocímetro ao objeto json de retorno do método
oJsonRet["gauge"] := oGauge:GetJsonObject()
FreeObj(oGauge)
Return
|
...






