#INCLUDE "PROTHEUS.CH"
#INCLUDE "TOPCONN.CH"
/*/{Protheus.doc} StatusOPExclusivo
Classe para prover os dados do Monitor de Status de Ordem de Producao Exclusivo
@type Class
@author
@since
@version
@return Nil
/*/
Class StatusOPExclusivo FROM LongNameClass
Static Method BuscaDados(oFiltros, cTipo, cSubTipo)
Static Method BuscaDetalhes(oFiltros, nPagina)
Static Method ValidaPropriedades(oFiltros)
EndClass
/*/{Protheus.doc} BuscaDados
Responsável por realizar a busca dos dados que serão exibidos no monitor
@type Class
@author
@since
@version
@param oFiltros , objeto Json, Contém as propriedades do monitor usadas para filtrar a query de busca
@param cTipo , caracter , Tipo chart/info
@param cSubTipo , caracter , Tipo de grafico pie/bar/column
@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 StatusOPExclusivo
Local aNames := {}
Local cAliasQry := GetNextAlias()
Local cJsonDados := ""
Local cOp := ""
Local cQuery := ""
Local cStatusFlt := ArrTokStr(oFiltros["STATUS"])
Local cStatusOp := ""
Local dDataIni := dDataBase
Local dDataFin := dDataBase
Local nIndice := 0
Local nIndSerie := 0
Local nPos := 0
Local nPosTag := 0
Local nTotOP := 0
Local oJsonRet := JsonObject():New()
Local oDados := JsonObject():New()
oJsonRet["alturaMinimaWidget"] := "350px"
oJsonRet["alturaMaximaWidget"] := "500px"
oJsonRet["categorias"] := {"Situação"}
oJsonRet["series"] := {}
oJsonRet["tags"] := {}
cQuery := montaQuery(oFiltros, @dDataIni, @dDataFin)
dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQuery),cAliasQry,.F.,.F.)
oDados["Prevista"] := {0, "rgb(255,255,0)"}
oDados["Em Aberto"] := {0, "rgb(126,226,148)"}
oDados["Iniciada"] := {0, "rgb(255,128,0)"}
oDados["Ociosa"] := {0, "rgb(128,128,128)"}
oDados["Enc. Parcialmente"] := {0, "rgb(0,0,165)"}
oDados["Enc. Totalmente"] := {0, "rgb(241,143,136)"}
nPos := 0
While (cAliasQry)->(!Eof())
cOp := (cAliasQry)->C2_NUM+(cAliasQry)->C2_ITEM+(cAliasQry)->C2_SEQUEN+(cAliasQry)->C2_ITEMGRD
cStatusOp := fStatusOp(cOp, (cAliasQry)->C2_TPOP, (cAliasQry)->C2_DATRF, (cAliasQry)->C2_QUJE, (cAliasQry)->C2_QUANT, (cAliasQry)->C2_DIASOCI, (cAliasQry)->C2_DATPRI)
If cStatusOp $ cStatusFlt
Do Case
Case cStatusOp == "1"
++oDados["Prevista"][1]
Case cStatusOp == "2"
++oDados["Em Aberto"][1]
Case cStatusOp == "3"
++oDados["Iniciada"][1]
Case cStatusOp == "4"
++oDados["Ociosa"][1]
Case cStatusOp == "5"
++oDados["Enc. Parcialmente"][1]
Case cStatusOp == "6"
++oDados["Enc. Totalmente"][1]
EndCase
EndIf
(cAliasQry)->(dbSkip())
End
(cAliasQry)->(dbCloseArea())
aNames := oDados:GetNames()
For nIndice := 1 To Len(aNames)
If cSubTipo <> "pie"
oDados[aNames[nIndice]][1] := {oDados[aNames[nIndice]][1]}
EndIf
PCPMonitorUtils():AdicionaSerieGraficoMonitor(oJsonRet["series"],@nIndSerie,oDados[aNames[nIndice]][2],oDados[aNames[nIndice]][1],aNames[nIndice])
nTotOP += oDados[aNames[nIndice]][1]
Next nIndice
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPosTag,"po-icon-calendar",dToC(dDataIni) + " - " + dToC(dDataFin))
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPosTag,"po-icon-star-filled",cValToChar(nTotOP) + IIF(nTotOP > 1," Ordens"," Ordem"))
If oFiltros:HasProperty("STATUS") .And. ValType(oFiltros["STATUS"]) == "A" .And. Len(oFiltros["STATUS"]) < 6
For nIndice := 1 To Len(oFiltros["STATUS"])
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPosTag,"po-icon-filter",buscaSerie(oFiltros["STATUS"][nIndice]))
Next nIndice
EndIf
If oFiltros:HasProperty("PRODUTO") .And. ValType(oFiltros["PRODUTO"]) == "A"
For nIndice := 1 To Len(oFiltros["PRODUTO"])
PCPMonitorUtils():AdicionaTagMonitor(oJsonRet["tags"],@nPosTag,"po-icon-bar-code",oFiltros["PRODUTO"][nIndice])
Next nIndice
EndIf
cJsonDados := oJsonRet:toJson()
FwFreeArray(aNames)
FreeObj(oDados)
FreeObj(oJsonRet)
Return cJsonDados
/*/{Protheus.doc} BuscaDetalhes
Responsável por realizar a busca dos dados que serão exibidos no detalhamento do monitor
@type Class
@author
@since
@version
@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 StatusOPExclusivo
Local cAliasQry := GetNextAlias()
Local cJsonDados := ""
Local cQuery := ""
Local cOp := ""
Local cStatusFlt := ArrTokStr(oFiltros["STATUS"])
Local cStatusOp := ""
Local dDataIni := dDataBase
Local dDataFin := dDataBase
Local lExpResult := .F.
Local nIndice := 0
Local nPos := 0
Local nPosTag := 0
Local nStart := 0
Local oDados := JsonObject():New()
Default nPagina := 1
Default nTamPagina := 20
If nPagina == 0
lExpResult := .T.
EndIf
cQuery := montaQuery(oFiltros, @dDataIni, @dDataFin)
dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQuery),cAliasQry,.F.,.F.)
oDados["items"] := {}
oDados["columns"] := montaColun(lExpResult)
oDados["headers"] := {}
oDados["tags"] := {}
oDados["canExportCSV"] := .T.
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nPosTag,"po-icon-calendar",dToC(dDataIni) + " - " + dToC(dDataFin))
If !Empty(oFiltros["SERIE"])
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nPosTag,"po-icon-filter",oFiltros["SERIE"])
Else
If oFiltros:HasProperty("STATUS") .And. ValType(oFiltros["STATUS"]) == "A" .And. Len(oFiltros["STATUS"]) < 6
For nIndice := 1 To Len(oFiltros["STATUS"])
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nPosTag,"po-icon-filter",buscaSerie(oFiltros["STATUS"][nIndice]))
Next nIndice
EndIf
EndIf
If oFiltros:HasProperty("PRODUTO") .And. ValType(oFiltros["PRODUTO"]) == "A"
For nIndice := 1 To Len(oFiltros["PRODUTO"])
PCPMonitorUtils():AdicionaTagMonitor(oDados["tags"],@nPosTag,"po-icon-bar-code",oFiltros["PRODUTO"][nIndice])
Next nIndice
EndIf
If nPagina > 1
nStart := ( (nPagina-1) * nTamPagina )
If nStart > 0
(cAliasQry)->(DbSkip(nStart))
EndIf
EndIf
nPos := 0
While (cAliasQry)->(!Eof())
cOp := (cAliasQry)->C2_NUM+(cAliasQry)->C2_ITEM+(cAliasQry)->C2_SEQUEN+(cAliasQry)->C2_ITEMGRD
cStatusOp := fStatusOp(cOp, (cAliasQry)->C2_TPOP, (cAliasQry)->C2_DATRF, (cAliasQry)->C2_QUJE, (cAliasQry)->C2_QUANT, (cAliasQry)->C2_DIASOCI, (cAliasQry)->C2_DATPRI, oFiltros["FILIAL"])
If !Empty(oFiltros["SERIE"])
If oFiltros["SERIE"] == buscaSerie(cStatusOp)
aAdd(oDados["items"], JsonObject():New())
nPos++
oDados["items"][nPos]["C2_FILIAL"] := (cAliasQry)->C2_FILIAL
oDados["items"][nPos]["C2_OP"] := Iif( !Empty((cAliasQry)->C2_OP), (cAliasQry)->C2_OP, cOp)
oDados["items"][nPos]["C2_PRODUTO"] := (cAliasQry)->C2_PRODUTO
oDados["items"][nPos]["B1_DESC"] := (cAliasQry)->B1_DESC
oDados["items"][nPos]["C2_LOCAL"] := (cAliasQry)->C2_LOCAL
oDados["items"][nPos]["C2_DATPRI"] := PCPMonitorUtils():FormataData((cAliasQry)->C2_DATPRI, 5)
oDados["items"][nPos]["C2_DATPRF"] := PCPMonitorUtils():FormataData((cAliasQry)->C2_DATPRF, 5)
oDados["items"][nPos]["C2_QUJE"] := (cAliasQry)->C2_QUJE
oDados["items"][nPos]["C2_QUANT"] := (cAliasQry)->C2_QUANT
oDados["items"][nPos]["C2_DIASOCI"] := (cAliasQry)->C2_DIASOCI
oDados["items"][nPos]["STATUS"] := cStatusOp
EndIf
Else
If cStatusOp $ cStatusFlt
aAdd(oDados["items"], JsonObject():New())
nPos++
oDados["items"][nPos]["C2_FILIAL"] := (cAliasQry)->C2_FILIAL
oDados["items"][nPos]["C2_OP"] := Iif( !Empty((cAliasQry)->C2_OP), (cAliasQry)->C2_OP, cOp)
oDados["items"][nPos]["C2_PRODUTO"] := (cAliasQry)->C2_PRODUTO
oDados["items"][nPos]["B1_DESC"] := (cAliasQry)->B1_DESC
oDados["items"][nPos]["C2_LOCAL"] := (cAliasQry)->C2_LOCAL
oDados["items"][nPos]["C2_DATPRI"] := PCPMonitorUtils():FormataData((cAliasQry)->C2_DATPRI, 5)
oDados["items"][nPos]["C2_DATPRF"] := PCPMonitorUtils():FormataData((cAliasQry)->C2_DATPRF, 5)
oDados["items"][nPos]["C2_QUJE"] := (cAliasQry)->C2_QUJE
oDados["items"][nPos]["C2_QUANT"] := (cAliasQry)->C2_QUANT
oDados["items"][nPos]["C2_DIASOCI"] := (cAliasQry)->C2_DIASOCI
oDados["items"][nPos]["STATUS"] := cStatusOp
EndIf
EndIf
(cAliasQry)->(dbSkip())
If !lExpResult .And. nPos >= nTamPagina
Exit
EndIf
End
oDados["hasNext"] := (cAliasQry)->(!Eof())
(cAliasQry)->(dbCloseArea())
cJsonDados := oDados:toJson()
FreeObj(oDados)
Return cJsonDados
/*/{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
@param lExpResult, logico, Indica se trata todas as colunas como visible
@return aColumns, array objetos, Contém as definições das colunas da grid do monitor
/*/
Static Function montaColun(lExpResult)
Local aColunas := {}
Local aLabels := {}
Local nIndice := 0
Local nIndLabels := 0
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"1","rgb(255,255,0)","Prevista","rgb(0,0,0)")
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"2","rgb(126,226,148)","Em aberto","rgb(255,255,255)")
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"3","rgb(255,128,0)","Iniciada","rgb(255,255,255)")
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"4","rgb(128,128,128)","Ociosa","rgb(255,255,255)")
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"5","rgb(0,0,165)","Enc. Parcialmente","rgb(255,255,255)")
PCPMonitorUtils():AdicionaLabelsColunaTabela(aLabels,@nIndLabels,"6","rgb(241,143,136)","Enc. Totalmente","rgb(255,255,255)")
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"STATUS","Status","cellTemplate",.T.,.T.,aLabels)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_FILIAL","Filial","string",lExpResult)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_OP","OP","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_PRODUTO","Produto","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"B1_DESC","Desc. Produto","string",lExpResult)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_LOCAL","Armazém","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_DATPRI","Previsão Início","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_DATPRF","Previsão Entrega","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_QUANT","Quantidade","string",.T.)
PCPMonitorUtils():AdicionaColunaTabela(aColunas,@nIndice,"C2_QUJE","Qtd. Prod","string",.T.)
Return aColunas
/*/{Protheus.doc} montaQuery
Realiza a criação de objeto Json que define as colunas utilizadas na grid de detalhamento do monitor
@type Static Function
@author
@since
@version
@param oFiltros, objeto Json, Contém as propriedades do monitor usadas para filtrar a query de busca
@param dDataIni, data , Data inicial do filtro
@param dDataFin, data , Data final do filtro
@return cQuery , caracter , Query utilizada para busca no banco de dados
/*/
Static Function montaQuery(oFiltros, dDataIni, dDataFin)
Local cPerDias := cValtoChar(oFiltros["PERIODO"])
Local cProdutos := ""
Local cQuery := ""
Local nIndice := 0
cQuery := " SELECT "
cQuery += " SC2.C2_FILIAL, SC2.C2_NUM, SC2.C2_ITEM, SC2.C2_SEQUEN, SC2.C2_ITEMGRD, SC2.C2_OP, SC2.C2_LOCAL,"
cQuery += " SC2.C2_PRODUTO, SB1.B1_DESC, SC2.C2_TPOP, SC2.C2_DATRF, SC2.C2_DATPRF, SC2.C2_QUJE, SC2.C2_QUANT, SC2.C2_DIASOCI, SC2.C2_DATPRI"
cQuery += " FROM " +RetSqlName("SC2")+ " SC2 "
cQuery += " LEFT JOIN "+RetSqlName("SB1")+" SB1 ON SB1.B1_FILIAL = '"+xFilial("SB1",oFiltros["FILIAL"])+"' AND SB1.B1_COD = SC2.C2_PRODUTO AND SB1.D_E_L_E_T_ = ' ' "
cQuery += " WHERE SC2.C2_FILIAL = '"+ xFilial("SC2", oFiltros["FILIAL"])+"' "
If oFiltros:HasProperty("PRODUTO") .And. ValType(oFiltros["PRODUTO"]) == "A"
For nIndice := 1 To Len(oFiltros["PRODUTO"])
If Empty(cProdutos)
cProdutos := "'" + oFiltros["PRODUTO"][nIndice] + "'"
Else
cProdutos += ",'" + oFiltros["PRODUTO"][nIndice] + "'"
EndIf
Next nIndice
EndIf
If !Empty(cProdutos)
cQuery += " AND SC2.C2_PRODUTO IN ("+cProdutos+") "
EndIf
If oFiltros["TIPOPERIODO"] == "X"
If Val(cPerDias) >= 0
dDataFin := PCPMonitorUtils():RetornaPeriodoFinal(oFiltros["TIPOPERIODO"],dDataIni,cPerDias)
Else
dDataIni := PCPMonitorUtils():RetornaPeriodoInicial(oFiltros["TIPOPERIODO"],dDataFin,cValtoChar(ABS(Val(cPerDias))))
EndIf
Else
dDataIni := PCPMonitorUtils():RetornaPeriodoInicial(oFiltros["TIPOPERIODO"],dDataFin,cPerDias)
dDataFin := PCPMonitorUtils():RetornaPeriodoFinal(oFiltros["TIPOPERIODO"],dDataIni,cPerDias)
EndIf
cQuery += " AND SC2."+oFiltros["FILTRODATA"]+" BETWEEN '"+dToS(dDataIni)+"' AND '"+dToS(dDataFin)+"' "
cQuery += " AND SC2.D_E_L_E_T_ = ' ' "
Return cQuery
/*/{Protheus.doc} Static Function fStatusOp
Retorna o Status da Ordem de Produção
@type Static Function
@author
@since
@version
@param cOP , caracter, Ordem de Produção
@param cTpo , caracter, Tipo da Ordem de Produção / Firme ou Prevista
@param cDatrf , caracter, Data de Encerramento
@param nQuje , numerico, Quantidade Apontada
@param nQuant , numerico, Quantidade Prevista
@param cFilterFil, caracter, Filial informada no filtro
@return cStatusOp , caracter, Status da OP - 1-Prevista/2-Em aberto/3-Iniciada/4-Ociosa/5-Enc.Parcialmente/6-Enc.Totalmente
/*/
Static Function fStatusOp(cOp, cTpo, cDatrf, nQuje, nQuant, cDatOci, cDTINI, cFilterFil)
Local cAliasTemp := ""
Local cQuery := ""
Local dEmissao := dDatabase
Local nRegSD3 := 0
Local nRegSH6 := 0
Default cOp := ""
Default cTpo := ""
Default cDatrf := ""
Default nQuant := 0
Default nQuje := 0
cDTINI := STOD(cDTINI)
If cTpo == "P" //1-Prevista
Return "1"
EndIf
If cTpo == "F" .And. !Empty(cDatrf) .And. (nQuje < nQuant) //5-Enc.Parcialmente
Return "5"
EndIf
If cTpo == "F" .And. !Empty(cDatrf) .And. (nQuje >= nQuant) //6-Enc.Totalmente
Return "6"
EndIf
cAliasTemp:= "SD3TMP"
cQuery := " SELECT COUNT(*) AS RegSD3, MAX(D3_EMISSAO) AS EMISSAO "
cQuery += " FROM " + RetSqlName("SD3")
cQuery += " WHERE D3_FILIAL = '" + xFilial( "SC2", cFilterFil ) + "'"
cQuery += " AND D3_OP = '" + cOp + "'"
cQuery += " AND D3_ESTORNO <> 'S' "
cQuery += " AND D_E_L_E_T_ = ' '"
cQuery += " GROUP BY D3_EMISSAO "
cQuery := ChangeQuery(cQuery)
dbUseArea (.T., "TOPCONN", TCGENQRY(,,cQuery), cAliasTemp, .F., .T.)
If !SD3TMP->(Eof())
dEmissao := STOD(SD3TMP->EMISSAO)
nRegSD3 := SD3TMP->RegSD3
EndIf
cAliasTemp:= "SH6TMP"
cQuery := " SELECT COUNT(*) AS REGSH6 "
cQuery += " FROM " + RetSqlName("SH6")
cQuery += " WHERE H6_FILIAL = '" + xFilial("SH6", cFilterFil) + "'"
cQuery += " AND H6_OP = '" + cOp + "'"
cQuery += " AND D_E_L_E_T_ = ' '"
cQuery := ChangeQuery(cQuery)
dbUseArea ( .T., "TOPCONN", TCGENQRY(,,cQuery), cAliasTemp, .F., .T.)
If !SH6TMP->(Eof())
nRegSH6 := SH6TMP->REGSH6
EndIf
SD3TMP->(DbCloseArea())
SH6TMP->(DbCloseArea())
If cTpo == "F" .And. Empty(cDatrf)
If (nRegSD3 < 1 .And. nRegSH6 < 1) .And. (Max(dDataBase - cDTINI,0) < If(cDatOci==0,1,cDatOci)) //2-Em aberto
Return "2"
EndIf
If (nRegSD3 > 0 .Or. nRegSH6 > 0) .And. (Max((ddatabase - dEmissao),0) > If(cDatOci >= 0,-1,cDatOci)) //3-Iniciada
Return "3"
EndIf
If (Max((ddatabase - dEmissao),0) > cDatOci .Or. Max((ddatabase - cDTINI),0) >= cDatOci) //4-Ociosa
Return "4"
EndIf
EndIf
Return
/*/{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 StatusOPExclusivo
Local aRetorno := {.T.,""}
PCPMonitorUtils():ValidaPropriedadeFilial(oFiltros["FILIAL"],aRetorno)
If aRetorno[1] .And. oFiltros["TIPOPERIODO"] == "X"
If !oFiltros:HasProperty("PERIODO") .Or. oFiltros["PERIODO"] == Nil .Or. Empty(oFiltros["PERIODO"])
aRetorno[1] := .F.
aRetorno[2] := "Deve ser informada a quantidade de dias para o período personalizado."
EndIf
EndIf
Return aRetorno
/*/{Protheus.doc} buscaSerie
Realiza um "De Para" buscando o texto relativo ao código de status das OPs
@type Static Function
@author
@since
@version
@param cStatusOp , caracter, Código do status da ordem de produção
@return cDscStatus, caracter, Descrição do status da ordem de produção
/*/
Static Function buscaSerie(cStatusOp)
Local cDscStatus := ""
Do Case
Case cStatusOp == "1"
cDscStatus := "Prevista"
Case cStatusOp == "2"
cDscStatus := "Em aberto"
Case cStatusOp == "3"
cDscStatus := "Iniciada"
Case cStatusOp == "4"
cDscStatus := "Ociosa"
Case cStatusOp == "5"
cDscStatus := "Enc. Parcialmente"
Case cStatusOp == "6"
cDscStatus := "Enc. Totalmente"
EndCase
Return cDscStatus |