Workflow Fluig integrado com Protheus

Como conectar Fluig (BPM TOTVS) ao Protheus pra aprovacoes, formularios, dashboards. Token, callbacks, sync de cadastros.

Fluig e a plataforma BPM da TOTVS — workflow visual, formularios, ECM. Integrado ao Protheus pra aprovacao de SC/PC/NF, processos de RH, qualquer fluxo que beneficie de UI rica.

Arquitetura

┌──────────────┐         ┌──────────────┐         ┌──────────────┐
│ Protheus     │ ──────→ │ Fluig BPM    │ ←────── │ Aprovador    │
│ (cria task)  │  REST   │ (humano)     │   UI    │ (web/mobile) │
└──────────────┘         └──────────────┘         └──────────────┘
       ↑                          │
       │   ←────── webhook ───────┘  (status atualizado)

Pre-requisitos

Etapa 1: Iniciar processo no Protheus

function IniciarAprovSC(cNumSC)
    Local oHttp := FwHttpClient():New()
    oHttp:SetHeader("Authorization", "Bearer " + GetTokenFluig())
    oHttp:SetHeader("Content-Type", "application/json")

    Local oForm := JsonObject():New()
    oForm["sc_numero"] := cNumSC
    oForm["sc_valor"]  := SC1->C1_TOTAL
    oForm["solicit"]   := SC1->C1_USER

    Local oPayload := JsonObject():New()
    oPayload["processId"]   := "aprov-sc-padrao"
    oPayload["formData"]    := oForm
    oPayload["startNodeId"] := "1"

    oHttp:Post("https://fluig.empresa.com.br/api/process-instance", oPayload:ToJson())

    Local oResp := JsonObject():New()
    oResp:FromJson(oHttp:GetBody())

    // Grava na SC1 o ID da instancia Fluig pra rastreio
    RecLock("SC1", .F.)
    SC1->C1_FLUIGID := oResp["instanceId"]
    SC1->(MsUnlock())
return

Etapa 2: Endpoint REST pra receber callback Fluig

@Post("/fluig/callback/aprov-sc")
function CallbackAprovSC()
    Local oBody := oRequest:getJsonBody()
    Local cInstanceId := oBody:getJsonObject("instanceId")
    Local cStatus     := oBody:getJsonObject("status")
    Local cAprovador  := oBody:getJsonObject("approver")

    // Localiza SC1
    SC1->(DBSetOrder(99))  // indice por fluigid
    If SC1->(DBSeek(cInstanceId))
        RecLock("SC1", .F.)
        SC1->C1_APROV  := If(cStatus == "APROVADO", "L", "B")
        SC1->C1_USRAPR := cAprovador
        SC1->C1_DTAPR  := dDataBase
        SC1->(MsUnlock())

        oResponse:setStatus(200)
        oResponse:setBody('{"status":"ok"}')
    Else
        oResponse:setStatus(404)
    EndIf
return

Etapa 3: Mapear dados Protheus → Fluig (formulario)

Em formularios Fluig, voce define campos que vem do Protheus. Fluig possui Datasets — APIs que ele consulta pra preencher formulario:

@Get("/fluig/dataset/clientes")
function DatasetClientes()
    Local oArr := JsonArray():New()

    SA1->(DBSetOrder(1))
    SA1->(DBSeek(xFilial("SA1")))
    While !SA1->(Eof()) .And. SA1->A1_FILIAL == xFilial("SA1")
        Local oCli := JsonObject():New()
        oCli["code"]  := AllTrim(SA1->A1_COD)
        oCli["name"]  := AllTrim(SA1->A1_NOME)
        oArr:Add(oCli)
        SA1->(DBSkip())
    EndDo

    oResponse:setContentType("application/json")
    oResponse:setBody(oArr:ToJson())
return

Pegadinhas

Casos de uso comuns

Veja também