#include "PROTHEUS.CH"
#include "FWMVCDEF.CH"
User Function NFCWFCUSTOM()
Local aAreas := {DHU->(GetArea()), SC8->(GetArea()), GetArea()}
Local oJsonWF := Paramixb[1]
Local oJsonResp := JsonObject():New()
Local oProcess := Nil
Local cNumCot := ''
Local nCode := 200
Local cMessage := ''
Local lOk := .T.
Local nX := 0
Local aSuppliers := {}
Local cFilialSC8 := FWxFilial('SC8')
Local cForn := ''
Local cLoja := ''
Local cForNome := ''
Local cEmail := ''
Local cLastProp := ''
Local cNomeWF := 'nfcwfcustom'
Local cMailBox := ''
Local cDirWF := AllTrim( WFGetMV( "MV_WFDIR", "" ) )
Local cSrLkWF := AllTrim( WFGetMV( "MV_WFBRWSR", "127.0.0.1:80" ) )
Local cHtmlMail1 := 'nfcwfcustom1.html' //-- Nome do arquivo HTML que será utilizado no envio do workflow
Local cHtmlMail2 := 'nfcwfcustom2.html' //-- Nome do arquivo HTML que será utilizado como corpo do e-mail
Local cProductDesc := ''
Local cIDWF := ''
Local cIDLink := ''
Local aTQuant := TamSX3("C8_QUANT")
Local aTQtDisp := TamSX3("C8_QTDISP")
Local aTPreco := TamSX3("C8_PRECO")
Local aTTotal := TamSX3("C8_TOTAL")
Local cUserLog := RetCodUsr()
Local nLenNum := TamSX3('C8_NUM')[1]
Local nLenForn := TamSX3('C8_FORNECE')[1]
Local nLenLoja := TamSX3('C8_LOJA')[1]
Local nLenForNome := TamSX3('C8_FORNOME')[1]
//-- Exemplo de estrutura do JSON contido em oJsonWF
/*
{
"quotation": "000230", // Número da cotação
"suppliers": [ //-- Array de fornecedores que receberão o workflow
{
"supplier": "000001", // Código do fornecedor
"store": "01", // Código da loja
"corporatename": "HOSPITAL MATER DEI", // Nome do fornecedor
"email": "[email protected]" // E-mail do fornecedor (pode conter mais de um e-mail separado por ponto e vírgula ex: "[email protected];[email protected]")
}
]
}
*/
//-- Cabeçalho da cotação
DHU->(DbSetOrder(1)) //-- DHU_FILIAL+DHU_NUM
cNumCot := padR(oJsonWF['quotation'], nLenNum)
If lOk := DHU->(DbSeek(FWxFilial('DHU') + cNumCot))
cMessage := "Processo de workflow enviado com sucesso."
//Exemplo de obtenção dos e-mails dos fornecedores para envio do workflow
aSuppliers := oJsonWF['suppliers']
For nX := 1 To Len(aSuppliers)
cForn := padR(aSuppliers[nX]['supplier'], nLenForn) //SC8->C8_FORNECE
cLoja := padR(aSuppliers[nX]['store'], nLenLoja) //SC8->C8_LOJA
cForNome := padR(aSuppliers[nX]['corporatename'], nLenForNome) //SC8->C8_FORNOME
cEmail := AllTrim(aSuppliers[nX]['email']) //Email preenchido no envio do workflow
cLastProp := PGCLastProp(cNumCot,cForn,cLoja,cForNome) //Função que retorna a última proposta do fornecedor (C8_NUMPRO)
// Aqui você pode implementar a lógica de envio do e-mail para o fornecedor
// Utilizando as variáveis cForn, cLoja, cForNome, cEmail e cLastProp
SC8->(DbSetOrder(8))
If !SC8->(DbSeek(cFilialSC8+cNumCot+cForn+cLoja+cForNome)) // Posiciona na Cotação do Fornecedor
cMessage := 'A proposta do fornecedor ' + AllTrim(cForNome) + ' não foi localizada na base de dados.'
lOk := .F.
Exit
EndIf
//-- Posiciona na proposta atual do fornecedor
While SC8->(!Eof()) .And. (cFilialSC8+cNumCot+cForn+cLoja+cLastProp+cForNome) <> SC8->(C8_FILIAL+C8_NUM+C8_FORNECE+C8_LOJA+C8_NUMPRO+C8_FORNOME)
SC8->(DbSkip())
EndDo
oProcess := TWFProcess():New(cNomeWF, DecodeUTF8(EncodeUTF8('Envio de Workflow para Cotação'))) // 'Envio de Workflow para Cotação'
If lOk := WF7->(MsSeek(FWxFilial('WF7')))
cMailBox := WF7->WF7_PASTA //-- Pode ser obtido na tabela WF7
Else
cMessage := 'Caixa de e-mail não cadastrada.'
Exit
EndIf
oProcess:oWf:cMailBox := cMailBox
oProcess:cFrom := cMailBox
oProcess:NewTask(cNomeWF, cDirWF + "\" + cHtmlMail1)
oProcess:cSubject := DecodeUTF8(EncodeUTF8('Solicitação de Cotação')) // 'Solicitação de Cotação'
oProcess:bReturn := 'u_WfCustom()' //-- Função de retorno quando o fornecedor responder o workflow
oProcess:bTimeOut := {{"__WFTimeout()", 0, 0, 5 }}
oProcess:oHTML:ValByName('cFilCot' , FWxFilial('DHU'))
oProcess:oHTML:ValByName('cNumCot' , SC8->C8_NUM)
oProcess:oHTML:ValByName('cFornece', SC8->C8_FORNECE)
oProcess:oHTML:ValByName('cLoja' , SC8->C8_LOJA)
oProcess:oHTML:ValByName('cForNome', cForNome)
oProcess:oHTML:ValByName('cNumProp', SC8->C8_NUMPRO)
oProcess:oHTML:ValByName('DHU_COND', SC8->C8_COND) //Condição de pagamento
//Strings do template HTML nfcwfcustom1.html
oProcess:oHTML:ValByName("cSTR1" , DecodeUTF8(EncodeUTF8("Solicitação de Cotação")))
oProcess:oHTML:ValByName("cSTR2" , DecodeUTF8(EncodeUTF8("Solicitação de Cotação - Nº")))
oProcess:oHTML:ValByName("cSTR3" , DecodeUTF8(EncodeUTF8("- Proposta")))
oProcess:oHTML:ValByName("cSTR4" , DecodeUTF8(EncodeUTF8("Fornecedor")))
oProcess:oHTML:ValByName("cSTR5" , DecodeUTF8(EncodeUTF8("Código / Loja")))
oProcess:oHTML:ValByName("cSTR6" , DecodeUTF8(EncodeUTF8("Filial Cotação")))
oProcess:oHTML:ValByName("cSTR7" , DecodeUTF8(EncodeUTF8("Itens da Cotação")))
oProcess:oHTML:ValByName("cSTR8" , DecodeUTF8(EncodeUTF8("Item")))
oProcess:oHTML:ValByName("cSTR9" , DecodeUTF8(EncodeUTF8("Produto")))
oProcess:oHTML:ValByName("cSTR10", DecodeUTF8(EncodeUTF8("Descrição")))
oProcess:oHTML:ValByName("cSTR11", DecodeUTF8(EncodeUTF8("Qtde")))
oProcess:oHTML:ValByName("cSTR12", DecodeUTF8(EncodeUTF8("Qtde Disp.")))
oProcess:oHTML:ValByName("cSTR13", DecodeUTF8(EncodeUTF8("Preço Unit.")))
oProcess:oHTML:ValByName("cSTR14", DecodeUTF8(EncodeUTF8("Total")))
oProcess:oHTML:ValByName("cSTR15", DecodeUTF8(EncodeUTF8("Observação")))
oProcess:oHTML:ValByName("cSTR16", DecodeUTF8(EncodeUTF8("Enviar")))
oProcess:oHTML:ValByName("cSTR17", DecodeUTF8(EncodeUTF8("Condição de pagamento")))
//-- Carrega itens da cotação referente a última proposta do fornecedor
While SC8->(!Eof()) .And. (cFilialSC8+cNumCot+cForn+cLoja+cForNome) == SC8->(C8_FILIAL+C8_NUM+C8_FORNECE+C8_LOJA+C8_FORNOME)
If cLastProp == SC8->C8_NUMPRO //-- Apenas a última proposta
Aadd(oProcess:oHTML:ValByName('It.C8_PRODUTO'), SC8->C8_PRODUTO)
Aadd(oProcess:oHTML:ValByName('It.C8_ITEM'), SC8->C8_ITEM)
cProductDesc := GetAdvFval("SB1","B1_DESC", FWxFilial('SB1') + SC8->C8_PRODUTO, 1)
Aadd(oProcess:oHTML:ValByName('It.cProDesc'), cProductDesc)
Aadd(oProcess:oHTML:ValByName('It.C8_QUANT'), Alltrim(STR(SC8->C8_QUANT,aTQuant[1],aTQuant[2])))
Aadd(oProcess:oHTML:ValByName('It.C8_QTDISP'), Alltrim(STR(SC8->C8_QTDISP,aTQtDisp[1],aTQtDisp[2])))
Aadd(oProcess:oHTML:ValByName('It.C8_PRECO'), Alltrim(STR(SC8->C8_PRECO ,aTPreco[1] ,aTPreco[2])))
Aadd(oProcess:oHTML:ValByName('It.C8_TOTAL'), Alltrim(STR(SC8->C8_TOTAL ,aTTotal[1] ,aTTotal[2])))
Aadd(oProcess:oHTML:ValByName('It.C8_OBS'), SC8->C8_OBS)
EndIf
SC8->(DbSkip())
EndDo
oProcess:oHTML:lUsaJS := .F.
oProcess:oWF:lHtmlBody := .T.
oProcess:cTo := cNomeWF
oProcess:UserSiga := cUserLog
oProcess:NewVersion(.T.)
cIDWF := oProcess:Start()
oProcess:NewTask(cNomeWF, cDirWF + '\' + cHtmlMail2)
oProcess:oHTML:ValByName('cNumCot' , cNumCot)
oProcess:oHTML:ValByName('cForNome' , cForNome)
oProcess:oHtml:ValByName('proc_link', cSrLkWF + '/messenger/emp' + cEmpAnt + '/'+cNomeWF+'/' + cIDWF + '.htm')
//Strings do template HTML nfcwfcustom2.html
oProcess:oHTML:ValByName("cSTR1", DecodeUTF8(EncodeUTF8("Solicitação de Cotação")))
oProcess:oHTML:ValByName("cSTR2", DecodeUTF8(EncodeUTF8("Solicitação de Cotação - Nº")))
oProcess:oHTML:ValByName("cSTR3", DecodeUTF8(EncodeUTF8("Olá,")))
oProcess:oHTML:ValByName("cSTR4", DecodeUTF8(EncodeUTF8("Você recebeu uma solicitação de cotação. Para visualizar e responder, acesse o link abaixo:")))
oProcess:oHTML:ValByName("cSTR5", DecodeUTF8(EncodeUTF8("Abrir Cotação")))
oProcess:oHTML:ValByName("cSTR6", DecodeUTF8(EncodeUTF8("Abrir cotação no navegador")))
oProcess:oHTML:ValByName("cSTR7", DecodeUTF8(EncodeUTF8("Se o botão não funcionar, copie e cole este endereço no seu navegador:")))
oProcess:cTo := cEmail //-- E-mail do fornecedor
oProcess:UserSiga := cUserLog
oProcess:NewVersion(.T.)
cIDLink := oProcess:Start()
If lOk := !Empty(cIDWF) .And. !Empty(cIDLink)
cMessage := "Workflow enviado com sucesso."
Else
cMessage := "Erro ao enviar o workflow para o fornecedor " + cForNome + "."
Exit
EndIf
Next nX
Else
cMessage := "A cotação não foi localizada na base dados."
EndIf
//Retorne o código 200 para sucesso ou 400 para erro
nCode := Iif(lOk, 200, 400)
oJsonResp["code"] := nCode
oJsonResp["message"] := cMessage
aEval(aAreas, {|x| RestArea(x), FwFreeArray(x) })
FwFreeArray(aTQuant)
FwFreeArray(aTQtDisp)
FwFreeArray(aTPreco)
FwFreeArray(aTTotal)
Return oJsonResp
//Função de exemplo que recebe a resposta do fornecedor
User Function WfCustom(oWorkflow)
Local cFilDHU := PADR(AllTrim(oWorkflow:oHtml:RetByName('cFilCot')), TAMSX3("C8_FILENT")[1])
Local cNumQuote := PADR(AllTrim(oWorkflow:oHtml:RetByName('cNumCot')), TAMSX3("C8_NUM")[1])
Local cCodFornec := PadR(RTrim(oWorkFlow:oHtml:RetByName('cFornece')), TAMSX3("C8_FORNECE")[1])
Local cLoja := PadR(RTrim(oWorkFlow:oHtml:RetByName('cLoja')), TAMSX3("C8_LOJA")[1])
Local cNomeFornec := PadR(RTrim(oWorkFlow:oHtml:RetByName('cForNome')), TAMSX3("C8_FORNOME")[1])
Local cNumProposta := PadR(RTrim(oWorkFlow:oHtml:RetByName('cNumProp')), TAMSX3("C8_NUMPRO")[1])
Local cProduto := ''
Local cItem := ''
Local oModel := nil
Local oMasterDHU := nil
Local oGridSC8 := nil
Local nX := 0
Local nPreco := 0
Local nQtdDisp := 0
DHU->( DbSetOrder(1) ) //DHU_FILIAL+DHU_NUM
If DHU->(DbSeek(cFilDHU + cNumQuote))
oModel := FwLoadModel("NFCA020")
oMasterDHU := oModel:GetModel("DHUMASTER")
oGridSC8 := oModel:GetModel("SC8DETAIL")
/*Chamar a seguinte função, informando número da cotação, código do fornecedor, nome do fornecedor e número da proposta, para que
ocorra a inicialização correta dos objetos JSON da rotina. Se não fizer, ocorrerá erro, pois os objetos estarão vazios e é ESSENCIAL chamar a rotina.*/
NF020SetSup(cNumQuote, cCodFornec, cLoja, cNomeFornec, cNumProposta)
oModel:SetOperation(MODEL_OPERATION_UPDATE)
oModel:Activate()
oMasterDHU:SetValue("DHU_COND", AllTrim(oWorkFlow:oHtml:RetByName('DHU_COND'))) //Condição de pagamento
If !oModel:HasErrorMessage()
//Editando os itens da cotação
for nX := 1 to Len(oWorkFlow:oHtml:RetByName('It.C8_PRODUTO'))
cProduto := oWorkFlow:oHtml:RetByName('It.C8_PRODUTO')[nX]
cItem := oWorkFlow:oHtml:RetByName('It.C8_ITEM')[nX]
If oGridSC8:SeekLine({{"C8_PRODUTO", cProduto}, {"C8_ITEM", cItem}})
nPreco := Val(oWorkFlow:oHtml:RetByName('It.C8_PRECO')[nX])
nQtdDisp := Val(oWorkFlow:oHtml:RetByName('It.C8_QTDISP')[nX])
oGridSC8:SetValue("C8_PRECO", nPreco)
oGridSC8:SetValue("C8_QTDISP", nQtdDisp)
oGridSC8:SetValue("C8_OBS", oWorkFlow:oHtml:RetByName('It.C8_OBS')[nX])
oGridSC8:SetValue('C8_WF' , .T.) //Marca o item como respondido via workflow
EndIf
next nX
//Calcular Impostos (Opcional)
NF020Calc()
EndIf
//Valido se o form está com informações corretas e consistentes
if ( !oModel:HasErrorMessage() .And. oModel:VldData() )
oModel:commitData()
else
//https://tdn.totvs.com/display/public/framework/FWFormModel - GetErrorMessage
FwLogMsg("ERROR",,AllTrim(oModel:getErrorMessage()[5]),,,,AllTrim(oModel:getErrorMessage()[5]) + " - " + AllTrim(oModel:getErrorMessage()[6]) + AllTrim(oModel:getErrorMessage()[7]))
endif
endif
oModel:DeActivate()
oModel:Destroy()
FWFreeObj(oModel)
FWFreeObj(oGridSC8)
return nil |