Árvore de páginas

01. DADOS GERAIS

Produto:

TOTVS Backoffice

Linha de Produto:

Linha Protheus

Segmento:

Backoffice

Módulo:

TOTVS Backoffice (Linha Protheus) - Compras (SIGACOM)

Função:NFC - ENVIO DE WORKFLOW
País:Brasil
Ticket:24289815
Requisito/Story/Issue (informe o requisito relacionado) :DBSUPINV-6054

02. DESCRIÇÃO

Descrição: Este ponto de entrada é utilizado para substituir a API de envio do workflow do NFC, podendo ser realizada qualquer implementação de workflow customizado.

Localização: NFC - Processos de envio do workflow (Geração da cotação, Envio de e-mail para o fornecedor, Novo participante e Nova proposta workflow).

Exemplos: Salvar os arquivos html com o título descrito no exemplo nfcwfcustom1.html e nfcwfcustom2.html


Importante

Ao ativar este ponto de entrada, o workflow padrão será integralmente substituído pelo workflow customizado. As telas de envio de e-mail serão simplificadas, exibindo apenas o campo para informar os endereços de e-mail e o botão de envio do workflow.

Exemplo NFCWFCUSTOM.prw
#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



Exemplo nfcwfcustom1.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="windows-1252">
    <meta charset="UTF-8">
    <title>%cSTR1%</title>
    <style>
      /* Estilos devem ficar inline nas tags */
    </style>
  </head>

  <body style="font:14px Arial, sans-serif; margin:12px;">

    <!-- Título -->
    <h1 style="font-size:18px; margin:0 0 8px 0;">
      %cSTR2% %cNumCot% %cSTR3% %cNumProp%
    </h1>

    <!-- Cabeçalho -->
    <table style="width:100%; border-collapse:collapse;">
      <tr>
        <td style="border:1px solid #ccc; padding:6px; width:180px;">%cSTR4%</td>
        <td style="border:1px solid #ccc; padding:6px;">%cForNome%</td>
      </tr>
      <tr>
        <td style="border:1px solid #ccc; padding:6px;">%cSTR5%</td>
        <td style="border:1px solid #ccc; padding:6px;">%cFornece% / %cLoja%</td>
      </tr>
      <tr>
        <td style="border:1px solid #ccc; padding:6px;">%cSTR6%</td>
        <td style="border:1px solid #ccc; padding:6px;">%cFilCot%</td>
      </tr>
    </table>

    <!-- Itens -->
    <form method="post" action="mailto:%25WFMailTo%25" style="margin:0; padding:0;">
      <h2 style="font-size:16px; margin:12px 0 6px 0;">%cSTR7%</h2>

      <table style="width:100%; border-collapse:collapse;">
        <thead>
          <tr>
            <th style="border:1px solid #ccc; padding:6px; text-align:left;">%cSTR8%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:left;">%cSTR9%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:left;">%cSTR10%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:right;">%cSTR11%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:right;">%cSTR12%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:right;">%cSTR13%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:right;">%cSTR14%</th>
            <th style="border:1px solid #ccc; padding:6px; text-align:left;">%cSTR15%</th>
          </tr>
        </thead>
        <tbody>
          <!-- Linha repetida pelo mecanismo do Workflow para cada item -->
          <tr class="item">
            <td style="border:1px solid #ccc; padding:6px;">%It.C8_ITEM%</td>
            <td style="border:1px solid #ccc; padding:6px;">%It.C8_PRODUTO%</td>
            <td style="border:1px solid #ccc; padding:6px;">%It.cProDesc%</td>

            <!-- Quantidade (numérico, somente leitura) -->
            <td style="border:1px solid #ccc; padding:6px; text-align:right;">
              <input type="number" name="It.C8_QUANT" class="C8_QUANT"
                    value="%It.C8_QUANT%" step="0.01" min="0" readonly
                    style="width:100%; height:28px; box-sizing:border-box; text-align:right; background:#f9f9f9;">
            </td>

            <!-- Qtde Disponível (numérico) -->
            <td style="border:1px solid #ccc; padding:6px; text-align:right;">
              <input type="number" name="It.C8_QTDISP" class="C8_QTDISP"
                    value="%It.C8_QTDISP%" step="0.01" min="0" oninput="gt(this)"
                    style="width:100%; height:28px; box-sizing:border-box; text-align:right;">
            </td>

            <!-- Preço Unitário (numérico) -->
            <td style="border:1px solid #ccc; padding:6px; text-align:right;">
              <input type="number" name="It.C8_PRECO" class="C8_PRECO"
                    value="%It.C8_PRECO%" step="0.01" min="0" oninput="gt(this)"
                    style="width:100%; height:28px; box-sizing:border-box; text-align:right;">
            </td>

            <!-- Total (numérico, calculado) -->
            <td style="border:1px solid #ccc; padding:6px; text-align:right;">
              <input type="number" name="It.C8_TOTAL" class="C8_TOTAL"
                    value="%It.C8_TOTAL%" step="0.01" min="0" readonly
                    style="width:100%; height:28px; box-sizing:border-box; text-align:right; background:#f9f9f9;">
            </td>

            <!-- Observação (texto) -->
            <td style="border:1px solid #ccc; padding:6px;">
              <input type="text" name="It.C8_OBS" class="C8_OBS" value="%It.C8_OBS%"
                    style="width:100%; height:28px; box-sizing:border-box;">
            </td>
          </tr>
        </tbody>
      </table>

      <!-- Hidden essentials -->
      <input type="hidden" name="cFilCot"  value="%cFilCot%">
      <input type="hidden" name="cNumCot"  value="%cNumCot%">
      <input type="hidden" name="cFornece" value="%cFornece%">
      <input type="hidden" name="cLoja"    value="%cLoja%">
      <input type="hidden" name="cForNome" value="%cForNome%">
      <input type="hidden" name="cNumProp" value="%cNumProp%">

      <!-- Rodapé (condição + enviar) -->
      <table style="width:100%; margin-top:10px;">
        <tr>
          <td style="padding:6px; vertical-align:middle;">
            <label for="DHU_COND" style="margin-right:6px; font-weight:bold;">%cSTR17%</label>
            <input type="text" name="DHU_COND" id="DHU_COND" value="%DHU_COND%"
                  style="width:240px; height:28px; box-sizing:border-box;">
          </td>
          <td style="padding:6px; text-align:right; vertical-align:middle;">
            <button type="submit"
                    style="min-width:140px; height:34px; border:1px solid #888; background:#eee; cursor:pointer;">
              %cSTR16%
            </button>
          </td>
        </tr>
      </table>
    </form>

    <!-- JS: Total = Preço × Qtde Disponível (linha atual) -->
    <script>
      function gt(el){
        var node = el;
        while (node && node.tagName !== 'TR') node = node.parentNode;
        if(!node) return;

        var qty = node.querySelector('.C8_QTDISP');
        var prc = node.querySelector('.C8_PRECO');
        var tot = node.querySelector('.C8_TOTAL');

        var q = parseFloat(((qty && qty.value) || '0').replace(',', '.'));
        var p = parseFloat(((prc && prc.value) || '0').replace(',', '.'));
        if (isNaN(q)) q = 0;
        if (isNaN(p)) p = 0;

        var val = q * p;
        if (tot) tot.value = val.toFixed(2);
      }
    </script>
  </body>
</html>
 



Exemplo nfcwfcustom2.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>%cSTR1%</title>
    <style>
      /* estilos devem ficar inline nas tags; bloco vazio proposital */
    </style>
  </head>

  <body style="font:14px Arial, sans-serif; margin:12px;">
    <!-- Título -->
    <h1 style="font-size:18px; margin:0 0 8px 0;">%cSTR2% %cNumCot%</h1>

    <!-- Mensagem -->
    <div style="border-top:1px solid #ccc; padding-top:10px; margin-top:10px;">
      <p style="margin:0 0 10px 0; line-height:1.4;">
        %cSTR3% <strong>%cForNome%</strong>. %cSTR4%
      </p>
    </div>

    <!-- Botão / CTA -->
    <div style="margin:10px 0;">
      <a href="!proc_link!" title="%cSTR6%"
        style="display:inline-block; padding:8px 14px; border:1px solid #888; background:#eee; text-decoration:none; color:#000;">
        %cSTR5%
      </a>
    </div>

    <!-- Fallback de link em texto -->
    <div style="margin:0 0 20px 0; font-size:13px; color:#333;">
      %cSTR7%<br>
      <span style="word-break:break-all;">!proc_link!</span>
    </div>
  </body>
</html>
 


03. DEMAIS INFORMAÇÕES

Quando este ponto de entrada está ativado, a tela de envio do workflow da cotação é resumida para conter apenas a opção de preenchimento dos e-mails e se envia ou não o workflow, não sendo possível utilizar todas as funcionalidades originais do workflow padrão.

Para receber o retorno do workflow customizado, é necessário utilizar a rotina automática NFCA020 conforme a documentação do Guia de referência - Novo Fluxo de Compras presente na sessão 07. PONTOS DE ENTRADA E ROTINA AUTOMÁTICA > Rotina automática - Edição da cotação.

04. ASSUNTOS RELACIONADOS

Guia de referência - Novo Fluxo de Compras

Função: WFTest

Função: TWFProcess