Árvore de páginas


CONTEÚDO

  1. Visão Geral
  2. Exemplo de utilização
  3. Tabelas utilizadas


01. VISÃO GERAL

Durante o processo de compensação em filiais diferentes da filial dos títulos, era realizada uma gravação incorreta na tabela FK7 (antes de Setembro de 2020). Essa gravação acabava impactando a sequência de baixa dos títulos envolvidos, gerando então o problema de não conseguir realizar o estorno corretamente.

Este rdmake realiza a correção da sequência de baixa das compensações afetadas pelo processo descrito acima.

Obs. O problema de gravação incorreta foi corrigido na issue DSERFINP-32706.

02. EXEMPLO DE UTILIZAÇÃO

IMPORTANTE!

O Rdmake foi realizado através do problema reportado na issue citada no tótico "Visão geral", sendo disponibilizado a correção somente para este cenário. Caso seja encontrado outros cenários a função de usuário esta disponível nesta documentação para personalização.


Como utilizar:

       1 - Realize um backup da base de dados 

       2 - Em um ambiente de homologação execute o Smartclient

       3 - No programa inicial, preencha "U_FA340FIX" e clique em "OK"

       4 - Na primeira tela apresentada, clique em "OK"

       5 - Na segunda tela apresentada, informe o código do grupo de empresas do ambiente que deseja reparar. Será preciso informar também uma filial deste grupo de empresa, apenas para inicializar o ambiente (deixamos claro que a         reparação será feita para todas as filiais do grupo de empresas). Clique em "OK"

      6 - O processamento será executado, e ao ser finalizado, nenhuma tela será apresentada, apenas a mensagem "Atualização concluída." no console do appserver

      7 - Valide a gravação das compensações que foram reparadas no banco de dados e no sistema.


São cobertos os seguintes cenários (compensação/estorno):

  • Compensação de NF com PA sem impostos
  • Compensação de NF com PA com correção monetária
  • Compensação de parcial de NF com PA
  • Compensação de NF com PA com acréscimo/decréscimo
  • Compensação com retenção de PCC/IRRF


Código fonte:
#INCLUDE "PROTHEUS.CH"
#INCLUDE "FWCOMMAND.CH"
 
#DEFINE CHAVEFK6 1
#DEFINE IDFK6    2
 
Static _oSeqAtu   := Nil
Static _oTmpEST   := Nil
Static _oTmpEST2  := Nil
Static _ValidCmp  := NIL
Static _VldMsmChv := NIL
Static _CmpParcOk := NIL
Static _lPccBaixa := Nil
Static _lIssBaixa := Nil
Static _lPaBruto  := Nil
Static _nTamDoc   := Nil
Static _nTamForn  := Nil
Static _aRecCM    := {}
 
//--------------------------------------------------------------------------
/*/{Protheus.doc}FA340FIX
Correcao das sequencias das compensacoes que foram feitas em
filial diferente da filial dos titulos
 
@since  14/08/2020
@version 12
/*/
//--------------------------------------------------------------------------
User Function FA340FIX()
 
    Local aSay      As Array
    Local aButton   As Array
    Local aEmp      As Array
    Local cTitulo   As Character
    Local cDesc1    As Character
    Local cDesc2    As Character
    Local cDesc3    As Character
    Local cDesc4    As Character
    Local lOk       As Logical
 
    Private oMainWnd  As Object
    Private oProcess  As Object
 
    aSay      := {}
    aButton   := {}
    cTitulo   := "Correcao de base - Compensacao CP"
    cDesc1    := "Este programa ira corrigir as sequencias da Compensacao CP. "
    cDesc2    := "Este processo deve ser executado em modo EXCLUSIVO, ou seja nao podem haver outros        "
    cDesc3    := "  usuarios  ou  jobs utilizando  o Financeiro.  E extremamente recomendavel  que  se  faca um"
    cDesc4    := "  BACKUP  da  BASE DE DADOS antes desta atualizacao.                   "
 
    aAdd(  aButton, {  1, .T., { || lOk := .T., FechaBatch() } } )
    aAdd(  aButton, {  2, .T., { || lOk := .F., FechaBatch() } } )
    aAdd( aSay, cDesc1 )
    aAdd( aSay, cDesc2 )
    aAdd( aSay, cDesc3 )
    aAdd( aSay, cDesc4 )
 
    FormBatch(  cTitulo,  aSay,  aButton )
 
    If lOk
        aEmp := {}
        aEmp := SelCompany()
 
        If !Empty( aEmp )
            oProcess := MsNewProcess():New( { | lEnd | lOk := FA340Process(aEmp) }, "Atualizando", "Aguarde, atualizando...", .F. )
            oProcess:Activate()
 
            If lOk
                Conout( "Atualizacao concluida." )
            Else
                Conout( "Atualizacao nao foi realizada." )
            EndIf
        EndIf
    EndIf
 
Return .T.
 
/*/
---------------------------------------------------------------------
    Reconstrucao de compensacoes CP
---------------------------------------------------------------------
/*/
Static Function FA340Process(aEmp As Array) As Logical
    Local aAreaAnt  as Array
    Local cChaveDoc as Character
    Local cChaveMov as Character
    Local cQuery    as Character
    Local lFirst    as Logical
    Local lRet      as Logical
    Local cIDAnt    as Character
    Local cIDFK2Ant as Character
    Local lMigrador as Logical
    Local lEstFK6   as Logical
    Local cIDFK6    as Character
    Local aEstFK6   as Array
    Local aCmpBa    as Array
    Local aCmpCp    as Array
    Local lProcOk   as Logical
    Local lAntProc  as Logical
    Local nQtdComp  as Numeric
 
    RpcSetType(3)
 
    RPCSetEnv(aEmp[1],aEmp[2], NIL, NIL, "FIN")
 
    _lPccBaixa := SuperGetMv("MV_BX10925", .F., "2") == "1"
    _lIssBaixa := SuperGetMv("MV_MRETISS",.F.,"1") == "2"
    _lPaBruto  := SuperGetMv("MV_PABRUTO", .F., "2") $ "1| "
    _nTamDoc   := TamSX3("E5_PREFIXO")[1]+TamSX3("E5_NUMERO")[1]+;
                    TamSX3("E5_PARCELA")[1]+TamSX3("E5_TIPO")[1]
    _nTamForn  := TamSX3("E5_CLIFOR")[1]+TamSX3("E5_LOJA")[1]
 
    aAreaAnt  := GetArea()
    lRet      := .F.
    cQuery    := ""
    cIDAnt    := ""
    lMigrador := .T.
    lEstFK6   := .F.
    cIDFK6    := ""
    aEstFK6   := {}
    aCmpBa    := {}
    aCmpCp    := {} 
    lProcOk   := .T.
    lAntProc  := .F.
 
    cQuery := "SELECT SE5.E5_PREFIXO, SE5.E5_NUMERO, SE5.E5_PARCELA, "
    cQuery += "SE5.E5_TIPO, SE5.E5_CLIFOR, SE5.E5_LOJA, SE5.E5_SITUACA, SE5.E5_TIPODOC, "
    cQuery += "SE5.E5_VLJUROS, SE5.E5_VLACRES, SE5.E5_VLDECRE, SE5.E5_DATA, "
    cQuery += "SE5.R_E_C_N_O_ RECSE5, SE5.E5_DOCUMEN, SE5.E5_VALOR, SE5.E5_FILORIG, "
    cQuery += "FK2.R_E_C_N_O_ RECFK2, FK2.FK2_FILIAL, FK2.FK2_IDDOC, "
    cQuery += "FK7.R_E_C_N_O_ RECFK7, FKA.R_E_C_N_O_ RECFKA, "
    cQuery +=       "(SELECT COUNT(CMP.FK2_IDDOC) FROM "+ RetSqlName("FK2") +" CMP" // Qtd. compensacoes p/ titulo
    cQuery +=       " WHERE CMP.FK2_FILIAL = FK7.FK7_FILIAL AND "
    cQuery +=       " CMP.FK2_IDDOC = FK7.FK7_IDDOC AND "
    cQuery +=       " CMP.FK2_MOTBX = 'CMP' AND CMP.FK2_RECPAG = 'P' AND"
    cQuery +=       " CMP.FK2_TPDOC <> 'ES' AND CMP.D_E_L_E_T_ = ' '"
    cQuery +=       ") QTDCMP, "
    cQuery +=       "( SELECT COUNT(EST.FK2_IDDOC) FROM "+ RetSqlName("FK2") +" EST"    // Qtd. Estornos da CMP
    cQuery +=       " WHERE EST.FK2_FILIAL = FK7.FK7_FILIAL AND"
    cQuery +=       " EST.FK2_IDDOC = FK7.FK7_IDDOC AND "
    cQuery +=       " EST.FK2_MOTBX = 'CMP' AND EST.FK2_RECPAG = 'R' AND"
    cQuery +=       " EST.FK2_TPDOC = 'ES' AND EST.D_E_L_E_T_ = ' '"
    cQuery +=       ") QTDEST "
    cQuery += " FROM "+ RetSqlName("SE5") +" SE5 "
    cQuery +=   "INNER JOIN "+ RetSqlName("FK2") +" FK2 "
    cQuery +=       "ON FK2.FK2_FILIAL = SE5.E5_FILIAL AND "
    cQuery +=           "FK2.FK2_IDFK2 = SE5.E5_IDORIG "
    cQuery +=    "INNER JOIN "+ RetSqlName("FK7") +" FK7 "
    cQuery +=       "ON FK2.FK2_FILIAL = FK7.FK7_FILIAL AND "
    cQuery +=           "FK2.FK2_IDDOC = FK7.FK7_IDDOC "
    cQuery +=    "INNER JOIN "+ RetSqlName("FKA") +" FKA "
    cQuery +=       "ON FKA.FKA_FILIAL = FK2.FK2_FILIAL AND "
    cQuery +=           "FKA.FKA_IDORIG = FK2.FK2_IDFK2 "
    cQuery += "WHERE FK2.FK2_FILORI <> FK7.FK7_FILIAL AND FK2.FK2_MOTBX = 'CMP' AND "
    cQuery += "FK2.FK2_RECPAG = 'P' AND FK2.FK2_TPDOC <> 'ES' AND "
    cQuery += "SE5.D_E_L_E_T_ = ' ' AND "
    cQuery += "FK2.D_E_L_E_T_ = ' ' AND "
    cQuery += "FKA.D_E_L_E_T_ = ' ' AND "
    cQuery += "FK7.D_E_L_E_T_ = ' '"
    cQuery += "ORDER BY SE5.E5_TIPODOC, SE5.E5_FILIAL, SE5.E5_PREFIXO, SE5.E5_NUMERO, SE5.E5_PARCELA, SE5.E5_TIPO, SE5.E5_CLIFOR, SE5.E5_LOJA"
 
    cQuery := ChangeQuery(cQuery)
    MpSysOpenQuery(cQuery,"E5TRB")
 
    dbSelectArea("SE2")
    dbSelectArea("SA2")
    dbSelectArea("SED")
    dbSelectArea("SE5")
    dbSelectArea("FK2")
    dbSelectArea("FKA")
    dbSelectArea("FK3")
    dbSelectArea("FK6")
 
    SE5->(dbSetOrder(2))
    FK2->(dbSetOrder(1))
    FK3->(dbSetOrder(2))
    FK6->(dbSetOrder(3))
 
    lFirst := .T.
 
    BEGIN TRANSACTION
        While E5TRB->(!EOF())
    
            lMigrador := .T.
            lEstFK6   := .T.
            lAntProc  := .F.
            lProcOk   := .T.

            cChaveDoc := E5TRB->E5_DOCUMEN
            cChaveMov := E5TRB->E5_PREFIXO + E5TRB->E5_NUMERO + E5TRB->E5_PARCELA +;
                                E5TRB->E5_TIPO + E5TRB->E5_CLIFOR + E5TRB->E5_LOJA

            FKA->(dbGoTo(E5TRB->RECFKA))
            FK2->(dbGoTo(E5TRB->RECFK2))
            FK7->(dbGoTo(E5TRB->RECFK7))

            If FK2->FK2_IDDOC == cIDAnt
                lMigrador := .F.
                lAntProc  := .T.
            EndIf

            cIDFK2Ant := FK2->FK2_IDFK2
            cIDAnt    := FK2->FK2_IDDOC    
            nQtdComp  := E5TRB->QTDCMP

            If E5TRB->E5_SITUACA == "C" .And. E5TRB->E5_TIPODOC $ "CM"
                lMigrador := .F.
                AAdd(aEstFK6,E5TRB->RECSE5)
            EndIf

            SE5->(dbGoTo(E5TRB->RECSE5))
            
            If lFirst .Or. !lAntProc
                If VerErroGrv(cChaveMov, E5TRB->FK2_FILIAL, SE5->E5_SEQ, E5TRB->QTDCMP, aCmpBa, @aCmpCp, @nQtdComp) //Verifica inconsistencia
                    lProcOk := .F.   
                EndIf

                If E5TRB->E5_TIPODOC $ "BA" .And. lProcOk
                    AAdd(aCmpBa, E5TRB->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA))
                EndIf
            EndIF

            If !lProcOk // Nao processa caso tenha erros
                E5TRB->(dbSkip())
                Loop 
            EndIf

            If lAntProc // Nao processa o mesmo titulo
                E5TRB->(dbSkip())
                Loop 
            EndIf

            CleanFKImp()
            CleanFK7()
            CleanFK2()     
            CleanFKA()

            SE5->(dbGoTo(E5TRB->RECSE5))
  
            If SE5->E5_TIPODOC $ "CP|BA"

                If E5TRB->E5_TIPO $ MVPAGANT+"|"+MV_CPNEG
                    If !Empty(SE5->E5_IDORIG) .And. lMigrador

                        //Atualiza sequencias da SE5
                        ATUSEQ(E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov,nQtdComp)

                        SE5->(dbGoTop()) // Somente para atualizar workarea
                        SE5->(dbGoTo(E5TRB->RECSE5))

                    EndIf

                    If E5TRB->QTDEST > 0
                        FixES(E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov,@aEstFK6,nQtdComp) // Procura e arruma estornos inconsistentes
                    EndIf
                EndIf
            Else   
                lMigrador := .F.
            EndIf
    
            If lMigrador
                FnBaixaE2(E5TRB->RECSE5,E5TRB->E5_FILORIG)
                
                SE5->(dbGoTo(E5TRB->RECSE5))
                
                If SE5->E5_VLJUROS > 0 .Or. SE5->E5_VLMULTA > 0 .Or. SE5->E5_VLDESCO > 0 .Or. SE5->E5_VLCORRE > 0
                    If E5TRB->QTDEST > 0
                        lEstFK6 := .T.
                    EndIf

                    SE5->(dbGoTo(E5TRB->RECSE5))
                    AtuFK6(cIDFK2Ant, SE5->E5_IDORIG, lEstFK6)
                Endif
            Endif

            E5TRB->(dbSkip())
    
            If lFirst
                lRet := .T.
                lFirst := .F.
            EndIf
    
        EndDo

    END TRANSACTION
 
    If !Empty(aEstFK6)
        AtuEsCm(aEstFK6)
    EndIf
     
    aSize(_aRecCM,0)
    _aRecCM := NIL
    DelTmps(_oSeqAtu)
    DelTmps(_oTmpEST)
    DelTmps(_ValidCmp)
    DelTmps(_VldMsmChv)
    DelTmps(_CmpParcOk)
 
    RestArea(aAreaAnt)
 
Return lRet
 
/*/
----------------------------------------------------------------------
    Atualiza os estornos de correçoes monetarias
----------------------------------------------------------------------
/*/
Static Function AtuEsCm(aEstFK6 As Array)
    Local cChvParc1 As Character
    Local cChvParc2 As Character
    Local cData     As Character
    Local cFil      As Character
    Local cTipoDoc  As Character
    Local cNewOrig  As Character
    Local nTamEST   As Numeric
    Local nX        As Numeric
    Local aAreaAnt  As Array
    Local cSeq      As Character
    Local nPosEST   As Numeric
 
    cChvParc1   := ""
    cChvParc2   := ""
    cData       := ""
    cFil        := ""
    cTipoDoc    := ""
    cNewOrig    := ""
    nTamEST     := Len(aEstFK6)
    nX          := 1
    cSeq        := ""
    nPosEST     := 0
 
    Default aEstFK6 := {}
 
    aAreaAnt := SE5->(GetArea())
    FK6->(dbSetOrder(3))
    SE5->(dbSetOrder(2))
 
    For nX := 1 To nTamEST
        SE5->(dbGoTo(aEstFK6[nX]))
 
        cChvParc1   := SE5->(E5_PREFIXO + E5_NUMERO + E5_PARCELA + E5_TIPO)
        cChvParc2   := SE5->(E5_CLIFOR + E5_LOJA)
        cData       := DTOS(SE5->E5_DATA)
        cFil        := SE5->E5_FILIAL
        cTipoDoc    := IIF(SE5->E5_TIPO $ MVPAGANT+"|"+MV_CPNEG, "BA","CP")
        cSeq        := SE5->E5_SEQ
         
        If !(SE5->E5_TIPODOC $ "BA|CP|ES")
            If SE5->(dbSeek(cFil+cTipoDoc+cChvParc1+cData+cChvParc2+cSeq))
                cNewOrig := SE5->E5_IDORIG
 
                SE5->(dbGoTo(aEstFK6[nX]))  
                RecLock("SE5",.F.)
                SE5->E5_IDORIG   := cNewOrig
                SE5->(MsUnlock())
            EndIf
        EndIf
 
        If (nPosEST := ASCAN(_aRecCM,{|x| x[CHAVEFK6] == cChvParc1 + cChvParc2 })) > 0
            If SE5->(dbSeek(cFil+"ES"+cChvParc1+cData+cChvParc2+cSeq))
                If FK6->(dbSeek(SE5->E5_FILIAL+_aRecCM[nPosEST][IDFK6]+"FK2"))
                    RecLock("FK6")
                    FK6->FK6_IDORIG := SE5->E5_IDORIG
                    FK6->(MsUnLock())
                EndIf
            EndIf
        EndIf
    Next nX
 
    RestArea(aAreaAnt)
 
Return Nil
 
/*/
----------------------------------------------------------------------
    Encontra os estornos incorretos das compensacoes para refaze-los
----------------------------------------------------------------------
/*/
Static Function FixES(cFil As Character, cDoc As Character, cChave As Character, aEstFK6 As Array, nQtdComp As Numeric)
 
    Local aAreaAnt   As Array
    Local aAreaSE5   As Array
    Local cQuery     As Character
    Local cIDFK2     As Character
    Local cCposChave As Character
    Local nValor     As Numeric
    Local nValorE5   As Numeric
    Local nValBA     As Numeric
 
    Default cFil      := ""
    Default cDoc      := ""
    Default cChave    := ""
    Default aEstFK6   := {}
    Default nQtdComp  := E5TRB->QTDCMP
 
    aAreaAnt := GetArea()
    aAreaSE5 := SE5->(GetArea())
    nValor   := 0
    nValorE5 := 0
    nValBA   := SE5->E5_VALOR
 
    BEGIN SEQUENCE
 
        If nQtdComp > 1  // 1 PA x Multi NFs
            If _oTmpEST == Nil
                cCposChave := " SE5.E5_PREFIXO || SE5.E5_NUMERO || SE5.E5_PARCELA || "
                cCposChave += " SE5.E5_TIPO || SE5.E5_CLIFOR || SE5.E5_LOJA CHAVE, "
 
                cQuery := "SELECT SE5.R_E_C_N_O_ RECSE5, SE5.E5_DOCUMEN, SE5.E5_FILORIG, SE5.E5_MOEDA, "
                cQuery += cCposChave + " SE5.E5_TIPO, SE5.E5_CLIFOR, SE5.E5_LOJA, SE5.E5_DATA, "
                cQuery += "SE5.E5_VLCORRE, SE5.E5_VLJUROS, SE5.E5_VLMULTA, SE5.E5_VLDESCO, "
                cQuery += "SE5.E5_IDORIG, SE5.E5_VALOR, SE5.E5_VLMOED2, SE5.E5_FILIAL, FK2.R_E_C_N_O_ RECFK2, "
                cQuery += "FK2.FK2_IDDOC "
                cQuery += "FROM "+ RetSqlName("SE5") +" SE5 "
                cQuery +=   "INNER JOIN "+ RetSqlName("FK2") +" FK2 "
                cQuery +=       "ON FK2.FK2_FILIAL = SE5.E5_FILIAL AND "
                cQuery +=           "FK2.FK2_IDFK2 = SE5.E5_IDORIG "
                cQuery += "WHERE "
                cQuery += "SE5.E5_FILIAL = ? AND "
                cQuery += "SE5.E5_DOCUMEN = ? AND "
                cQuery += "SE5.E5_RECPAG = 'R' AND SE5.E5_TIPODOC = 'ES' AND "
                cQuery += "FK2.FK2_RECPAG = 'R' AND FK2.FK2_TPDOC = 'ES' AND "
                cQuery += "SE5.D_E_L_E_T_ = ' ' AND "
                cQuery += "FK2.D_E_L_E_T_ = ' ' "
                cQuery += "ORDER BY SE5.R_E_C_N_O_"
 
                cQuery := ChangeQuery(cQuery)
                _oTmpEST := FWPreparedStatement():New(cQuery)
            EndIf
 
            _oTmpEST:SetString(1,cFil)
            _oTmpEST:SetString(2,cChave)
 
            cQuery := _oTmpEST:GetFixQuery()
            MpSysOpenQuery(cQuery,"FIXES")
 
            SE5->(dbSetOrder(2)) //e5_filial, e5_tipodoc, e5_prefixo, e5_numero, e5_parcela, e5_tipo, e5_data, e5_clifor, e5_loja
 
            While FIXES->(!EOF())
                If SE5->(dbSeek(cFil+"ES"+Left(FIXES->E5_DOCUMEN,_nTamDoc)+FIXES->E5_DATA+SubStr(FIXES->E5_DOCUMEN,_nTamDoc+1,_nTamForn)))
                    cIDFK2 := SE5->E5_IDORIG
                    If FIXES->E5_MOEDA <> SE5->E5_MOEDA
                        If FIXES->E5_MOEDA <> "01"
                            nValor := FIXES->E5_VLMOED2
                        Else
                            nValor := FIXES->E5_VALOR
                        EndIf
 
                        If SE5->E5_MOEDA <> "01"
                            nValorE5 := SE5->E5_VLMOED2
                        Else
                            nValorE5 := SE5->E5_VALOR
                        EndIf
                    Else
                        nValor := FIXES->E5_VALOR
                        nValorE5 := SE5->E5_VALOR
                    EndIf
                    If nValorE5 <> nValor .Or. RTrim(SE5->E5_DOCUMEN) <> FIXES->CHAVE // Se valor for diferente, sabemos que eh a perna errada do estorno
                        If FIXES->E5_VLCORRE > 0 .Or. FIXES->E5_VLJUROS > 0 .Or. FIXES->E5_VLMULTA > 0 .Or. FIXES->E5_VLDESCO
                            aAdd(_aRecCM,{FIXES->CHAVE, FIXES->E5_IDORIG})
                            aAdd(aEstFK6, FIXES->RECSE5)
                        Endif
 
                        If SE5->E5_VLCORRE > 0 .Or. SE5->E5_VLJUROS > 0 .Or. SE5->E5_VLMULTA > 0 .Or. SE5->E5_VLDESCO
                            aAdd(_aRecCM, { SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA), SE5->E5_IDORIG})
                            aAdd(aEstFK6, SE5->(RECNO()))
                        Endif
 
                        FixSE2("SE5",SE5->E5_FILORIG,FIXES->E5_DOCUMEN,"-") // Desfaz estorno incorreto da compensacao
                        FixSE5("FIXES",aAreaSE5)    // Corrige perna do estorno na SE5
                        If FK2->(dbSeek(cFil+cIDFK2))    // Deleta 1a perna do estorno na FK2
                            CleanFK2()
                        EndIf
                        If FK2->(dbSeek(cFil+FIXES->E5_IDORIG))   // Deleta 2a perna do estorno na FK2
                            CleanFK2()
                        EndIf
                         
                        FixSE2("SE5",FIXES->E5_FILORIG,FIXES->E5_DOCUMEN,"+")
                    Else 
                        FixSE5("FIXES",aAreaSE5) 
                    EndIf
                EndIf
                FIXES->(dbSkip())
            EndDo
        Else    // 1 NF x Multi PAs
            If _oTmpEST2 == Nil
                cCposChave := " SE5.E5_PREFIXO || SE5.E5_NUMERO || SE5.E5_PARCELA || "
                cCposChave += " SE5.E5_TIPO || SE5.E5_CLIFOR || SE5.E5_LOJA CHAVE, "
 
                cQuery := "SELECT SE5.R_E_C_N_O_ RECSE5, SE5.E5_DOCUMEN, SE5.E5_FILORIG, SE5.E5_MOEDA, "
                cQuery += cCposChave + " SE5.E5_TIPO, SE5.E5_CLIFOR, SE5.E5_LOJA, SE5.E5_DATA, "
                cQuery += "SE5.E5_VLCORRE, SE5.E5_VLJUROS, SE5.E5_VLMULTA, SE5.E5_VLDESCO, "
                cQuery += "SE5.E5_VLACRES, SE5.E5_VLDECRE, SE5.E5_FILIAL, SE5.E5_VRETIRF, "
                cQuery += "SE5.E5_VRETCOF, SE5.E5_VRETCSL, SE5.E5_VRETPIS, SE5.E5_VRETISS, "
                cQuery += "SE5.E5_IDORIG, SE5.E5_VALOR, SE5.E5_SEQ, SE5.E5_VLMOED2, FK2.R_E_C_N_O_ RECFK2, "
                cQuery += "FK2.FK2_IDDOC "
                cQuery += "FROM "+ RetSqlName("SE5") +" SE5 "
                cQuery +=   "INNER JOIN "+ RetSqlName("FK2") +" FK2 "
                cQuery +=       "ON FK2.FK2_FILIAL = SE5.E5_FILIAL AND "
                cQuery +=           "FK2.FK2_IDFK2 = SE5.E5_IDORIG "
                cQuery += "WHERE "
                cQuery += "SE5.E5_FILIAL = ? AND "
                cQuery += "SE5.E5_PREFIXO || SE5.E5_NUMERO || SE5.E5_PARCELA || "
                cQuery += "SE5.E5_TIPO || SE5.E5_CLIFOR || SE5.E5_LOJA = ? AND "
                cQuery += "SE5.E5_RECPAG = 'R' AND SE5.E5_TIPODOC = 'ES' AND "
                cQuery += "FK2.FK2_RECPAG = 'R' AND FK2.FK2_TPDOC = 'ES' AND "
                cQuery += "SE5.D_E_L_E_T_ = ' ' AND "
                cQuery += "FK2.D_E_L_E_T_ = ' ' "
                cQuery += "ORDER BY SE5.R_E_C_N_O_"
 
                cQuery := ChangeQuery(cQuery)
                _oTmpEST2 := FWPreparedStatement():New(cQuery)
            EndIf
 
            _oTmpEST2:SetString(1,cFil)
            _oTmpEST2:SetString(2,RTrim(cDoc))
 
            cQuery := _oTmpEST2:GetFixQuery()
            MpSysOpenQuery(cQuery,"FIXES")
 
            dbSelectArea("SE5")
            While FIXES->(!EOF())
                SET FILTER TO SE5->E5_FILIAL == cFil .and.;
                    RTrim(SE5->E5_DOCUMEN) == RTrim(FIXES->CHAVE) .and.;
                    SE5->E5_TIPODOC == "ES" .and. SE5->E5_SEQ == FIXES->E5_SEQ .and.;
                    SE5->E5_VALOR <> FIXES->E5_VALOR
 
                SE5->(dbGoTop())
 
                cIDFK2 := FIXES->E5_IDORIG
                If FIXES->E5_MOEDA <> SE5->E5_MOEDA
                    If FIXES->E5_MOEDA <> "01"
                        nValor := FIXES->E5_VLMOED2
                    Else
                        nValor := FIXES->E5_VALOR
                    EndIf
 
                    If SE5->E5_MOEDA <> "01"
                        nValorE5 := SE5->E5_VLMOED2
                    Else
                        nValorE5 := SE5->E5_VALOR
                    EndIf
                Else
                    nValor := FIXES->E5_VALOR
                    nValorE5 := SE5->E5_VALOR
                EndIf
                If nValor <> nValorE5 .Or.;   // Se valor for diferente, sabemos que eh a perna errada do estorno
                        RTrim(FIXES->E5_DOCUMEN) <> SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA)
 
                    If FIXES->E5_VLCORRE > 0 .Or. FIXES->E5_VLJUROS > 0 .Or. FIXES->E5_VLMULTA > 0 .Or. FIXES->E5_VLDESCO
                        aAdd(_aRecCM,{FIXES->CHAVE, FIXES->E5_IDORIG})
                        aAdd(aEstFK6, FIXES->RECSE5)
                    Endif
 
                    If SE5->E5_VLCORRE > 0 .Or. SE5->E5_VLJUROS > 0 .Or. SE5->E5_VLMULTA > 0 .Or. SE5->E5_VLDESCO
                        aAdd(_aRecCM, { SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA), SE5->E5_IDORIG})
                        aAdd(aEstFK6, SE5->(RECNO()))
                    Endif

                    If SE5->E5_VALOR <> nValBA
                        If SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA) == FIXES->E5_DOCUMEN
                            FixSE2("FIXES",SE5->E5_FILORIG,SE5->E5_DOCUMEN,"-") // Desfaz estorno incorreto da compensacao
                            FixSE5("SE5",aAreaSE5)  // Corrige perna do estorno na SE5
                            If FK2->(dbSeek(cFil+cIDFK2))    // Deleta 1a perna do estorno na FK2
                                CleanFK2()
                            EndIf
                            If FK2->(dbSeek(cFil+SE5->E5_IDORIG)) // Deleta 2a perna do estorno na FK2
                                CleanFK2()
                            EndIf
                            FixSE2("SE5",SE5->E5_FILORIG,SE5->E5_DOCUMEN,"+")
                        EndIf
                    Else
                        FixSE5("SE5",aAreaSE5)
                    EndIf
                EndIf
                FIXES->(dbSkip())
            EndDo
            If nValor <> 0
                SE5->(dbClearFilter())
            EndIf
        EndIf
 
        FIXES->(dbCloseArea())
 
    END SEQUENCE
 
    RestArea(aAreaAnt)
 
    RestArea(aAreaSE5)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Desfaz a compensacao nos titulos para refazer depois
---------------------------------------------------------------------
/*/
Static Function FixSE2(cAlias As Character, cFil As Character, cChave As Character,cOper As Character)
 
    Local aAreaAnt  As Array
    Local nSaldo    As Numeric
 
    Default cAlias   := "SE5"
    Default cFil     := SE5->E5_FILORIG
    Default cChave   := SE5->E5_DOCUMEN
    Default cOper    := "+"
 
    aAreaAnt := GetArea()
 
    SE2->(dbSetOrder(1))
    If SE2->(dbSeek(cFil+RTrim(cChave))) .and. !Empty(SE2->E2_BAIXA)  // Verifica se o titulo ja foi reconstituido
        SA2->(dbSetOrder(1))
        SA2->(dbSeek(xFilial("SA2",SE2->E2_FILORIG)+SE2->(E2_FORNECE+E2_LOJA)))
        nSaldo := MontaSaldo(cAlias)
        RecLock("SE2",.F.)
        If cOper == "-" // Subtrai, desfazendo estorno incorreto
            SE2->E2_SALDO     -= nSaldo
            SE2->E2_SDACRES   -= (cAlias)->E5_VLACRES
            SE2->E2_SDDECRE   -= (cAlias)->E5_VLDECRE
        Else    // Soma, refazendo estorno correto
            SE2->E2_SALDO     += nSaldo
            SE2->E2_SDACRES   += (cAlias)->E5_VLACRES
            SE2->E2_SDDECRE   += (cAlias)->E5_VLDECRE
        EndIf
        MsUnlock()
    EndIf
    RestArea(aAreaAnt)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Corrige os estornos de compensacoes na SE5
---------------------------------------------------------------------
/*/
Static Function FixSE5(cAlias As Character, aAreaSE5 As Array)
     
    Local aAreaAnt  As Array
    Local cSeq      As Character
    Local nValor    As Numeric
    Local nVLMD2    As Numeric
    Local cDocumen  As Character
    Local cChave    As Character
    Local cTipo     As Character
    Local cFil      As Character
    Local nAuxVal   As Numeric
 
    Default cAlias   := "SE5"
    Default aAreaSE5 := SE5->(GetArea())
 
    aAreaAnt := SE5->(GetArea())
    nValor   := (cAlias)->E5_VALOR
    nVLMD2   := (cAlias)->E5_VLMOED2
    cDocumen := (cAlias)->E5_DOCUMEN
    cTipo    := IIF((cAlias)->E5_TIPO $ MVPAGANT+"|"+MV_CPNEG, "BA", "CP")
    cSeq     := ""
    cFil     := (cAlias)->E5_FILIAL
 
    If cAlias == "FIXES"
        cChave   := (cAlias)->CHAVE 
    Else
        cChave   := (cAlias)->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA)
    EndIf
 
    dbSelectArea("SE5")
    SET FILTER TO SE5->E5_FILIAL == cFil .and.;
                RTrim(SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA)) == cChave .and.;
                RTrim(SE5->E5_DOCUMEN) == RTrim(cDocumen) .and.;
                SE5->E5_TIPODOC == cTipo
        SE5->(dbGoTop())
        cSeq := SE5->E5_SEQ  // Pega seq. atualizada
    SE5->(dbClearFilter())
    RestArea(aAreaAnt)
 
    If cAlias == "SE5"
        SE5->(dbSetOrder(2))
        SE5->(dbSeek(cFil+"ES"+Left((cAlias)->E5_DOCUMEN,_nTamDoc)+DTOS((cAlias)->E5_DATA)+SubStr((cAlias)->E5_DOCUMEN,_nTamDoc+1,_nTamForn)))
    EndIf
 
    If FIXES->E5_MOEDA <> SE5->E5_MOEDA  //Em casos de moeda estrangeiro inverte os valores
        nAuxVal := nValor
        nValor  := nVLMD2
        nVLMD2  := nAuxVal
    EndIf
 
    If SE5->(!EOF())
        RecLock("SE5",.F.)
        SE5->E5_DOCUMEN := cChave
        SE5->E5_VALOR    := nValor
        SE5->E5_VLMOED2  := nVLMD2
        SE5->E5_SEQ      := cSeq
        SE5->(MsUnlock())
 
        SE5->(DbSetOrder(7))
        If SE5->(dbSeek(SE5->E5_FILIAL + Rtrim(cChave)))
            SeqRecord(cSeq) // Atualiza estorno
        EndIf
    EndIf
 
    RestArea(aAreaAnt)
 
Return
 
/*/
---------------------------------------------------------------------
    Recompoe saldo dos titulos estornados incorretamente
---------------------------------------------------------------------
/*/
Static Function MontaSaldo(cAlias As Character) As Numeric
 
    Local nSaldo    As Numeric
    Local lIrfBaixa As Logical
 
    Default cAlias := "SE5"
 
    lIrfBaixa := SA2->A2_CALCIRF == "2" .AND.  !SE2->E2_TIPO $ MVPAGANT .And.;
                (Posicione("SED",1,xFilial("SED",SE2->E2_FILORIG)+SE2->E2_NATUREZ,"ED_CALCIRF") == "S")
 
    nSaldo := (cAlias)->E5_VALOR
 
    If lIrfBaixa
        nSaldo += (cAlias)->E5_VRETIRF
    EndIf
    If _lPccBaixa
        nSaldo += (cAlias)->(E5_VRETPIS+E5_VRETCOF+E5_VRETCSL)
    EndIf
    If _lIssBaixa
        nSaldo += (cAlias)->E5_VRETISS
    EndIf
 
Return nSaldo
 
/*/
---------------------------------------------------------------------
    Atualiza sequencias de compensacoes na SE5
---------------------------------------------------------------------
/*/
Static Function ATUSEQ(cFil As Character, cDoc As Character, cChave As Character, nQtdComp As Numeric)
    Local aAreaAnt  As Array
    Local cChavePai As Character
    Local lMultSeq  As Logical
    Local cCountSeq As Character
    Local lFlush    As Logical
    Local cQuery    As Character
    Local aAreaSE5  As Array
    Local nRecAnt   As Numeric
    Local cDocNf    As Character
    Local lFindDoc  As Logical
 
    Default cFil      := ""
    Default cDoc      := ""
    Default cChave    := ""
    Default E5TRB     := Alias()
    Default nQtdComp  := E5TRB->QTDCMP
 
    aAreaAnt   := GetArea()
    aAreaSE5   := SE5->(GetArea())
    lMultSeq   := lFlush := .F.
    cCountSeq  := SE5->E5_SEQ
    cQuery     := "" 
    cDocNf     := ""
    nRecAnt    := 0
    lFindDoc   := .T.

    If nQtdComp > 1
        If !VerMsmChv(SE5->(RECNO()))
            lFindDoc := .F.
        EndIf
    EndIf
 
    If _oSeqAtu == Nil
        cQuery := " SELECT R_E_C_N_O_ RECNO FROM " + RetSqlName("SE5")
        cQuery += " WHERE"
        cQuery += " E5_FILIAL = ? AND "
        cQuery += " E5_DOCUMEN = ? AND "
        cQuery += " E5_RECPAG = 'P' AND E5_TIPODOC <> 'ES' AND "
        cQuery += " D_E_L_E_T_ = ' ' "
        cQuery += " ORDER BY R_E_C_N_O_ "
 
        cQuery := ChangeQuery(cQuery)
        _oSeqAtu := FWPreparedStatement():New(cQuery)
    EndIf  
 
    _oSeqAtu:SetString(1,cFil)
    _oSeqAtu:SetString(2,IIf(lFindDoc,RTrim(cDoc),cChave))
 
    cQuery := _oSeqAtu:GetFixQuery()
    MpSysOpenQuery(cQuery,"E5SEQ")
 
    While E5SEQ->(!EOF())

        SE5->(dbGoTo(E5SEQ->RECNO))
        
        If lMultSeq
            cCountSeq := Soma1(cCountSeq)
        Else
            cCountSeq := SE5->E5_SEQ
            lFlush    := .T.
            lMultSeq  := .T.
        EndIf
 
        cChavePai  := SE5->(E5_PREFIXO + E5_NUMERO + E5_PARCELA + E5_TIPO + E5_CLIFOR + E5_LOJA)
 
        //Atualiza sequencia do titulo de destino
        SeqRecord(cCountSeq)
        ChkMovCompl(cCountSeq)
 
        cDocNf := RTrim(SE5->E5_DOCUMEN)
         
        dbSelectArea("SE5")
        SET FILTER TO SE5->E5_FILIAL == cFil .and.;
                    SE5->(RECNO()) <> nRecAnt .and.;
                    RTrim(SE5->E5_DOCUMEN) == RTrim(cChavePai) .and.;
                    RTrim(SE5->(E5_PREFIXO+E5_NUMERO+E5_PARCELA+E5_TIPO+E5_CLIFOR+E5_LOJA)) == cDocNf
                       
 
        SE5->(dbGoTop())
        nRecAnt := SE5->(Recno())
 
        //Atualiza sequencia do titulo de partida
        SeqRecord(cCountSeq)
        ChkMovCompl(cCountSeq)

        SE5->(dbClearFilter())
 
        E5SEQ->(dbSkip())
    EndDo  
     
    If lFlush
        SE5->(FKCommit())
    EndIf
     
    RestArea(aAreaSE5)
    RestArea(aAreaAnt)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Deleta referencias incorretas da FKA
---------------------------------------------------------------------
/*/
Static Function CleanFKA()
 
    If FKA->(!EoF())
        RecLock("FKA")
        FKA->(DbDelete())
        FKA->(MsUnLock())
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Deleta referencias incorretas da FK2
---------------------------------------------------------------------
/*/
Static Function CleanFK2()
 
    If FK2->(!EoF())
        RecLock("FK2")
        FK2->(DbDelete())
        FK2->(MsUnLock())
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Deleta referencias incorretas da FK3 e FK4
---------------------------------------------------------------------
/*/
Static Function CleanFKImp()
 
    Local aArea     As Array
    Local cFilter   As Character
 
    aArea := GetArea()
    cFilter:= ""
 
    If FK3->(dbSeek(FK2->FK2_FILIAL+"FK2"+FK2->FK2_IDFK2))
        dbSelectArea("FK4")
        cFilter := FK4->(dbFilter())
        While FK3->(!EOF()) .and. FK3->FK3_FILIAL == FK2->FK2_FILIAL .and.;
              FK3->FK3_IDORIG == FK2->FK2_IDFK2 .and. FK3->FK3_TABORI == "FK2"
 
            SET FILTER TO FK4->FK4_FILIAL == FK3->FK3_FILIAL .and.;
                          FK4->FK4_IDFK4 == FK3->FK3_IDRET
 
            FK4->(dbGoTop())
            If FK4->(!EoF())
                RecLock("FK4")
                FK4->(DbDelete())
                FK4->(MsUnLock())
            EndIf
     
            RecLock("FK3")
            FK3->(DbDelete())
            FK3->(MsUnLock())
            FK3->(dbSkip())
        EndDo
        If Empty(cFilter)
            FK4->(dbClearFilter())
        Else
            SET FILTER TO &cFilter
        EndIf
    EndIf
 
    RestArea(aArea)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Deleta referencias incorretas da FK6
---------------------------------------------------------------------
/*/
Static Function AtuFK6(cIDFK2 As Character, cFK2Atu As Character, lEstFK6 As Logical)
 
    Local aArea     As Array
 
    Default cIDFK2  := cFK2Atu:= FK2->FK2_IDFK2
    Default lEstFK6 := .F.
 
    aArea := GetArea()
 
    FK6->(dbSetOrder(3))
    If FK6->(dbSeek(FK2->FK2_FILIAL+cIDFK2+"FK2"))
        While FK6->(!EOF()) .and. FK6->FK6_FILIAL == FK2->FK2_FILIAL .and.;
              FK6->FK6_IDORIG == cIDFK2 .and. FK6->FK6_TABORI == "FK2"
 
             
            RecLock("FK6")
            If FK6->FK6_TPDOC == "CM" .And. !lEstFK6
                FK6->(DBDelete())
            Else
                FK6->FK6_IDORIG := cFK2Atu
            EndIf
            FK6->(MsUnLock())
             
            FK6->(dbSkip())
        EndDo
    EndIf
 
    RestArea(aArea)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Deleta referencias incorretas da FK7
---------------------------------------------------------------------
/*/
Static Function CleanFK7()
 
    If !SE2->(dbSeek(STRTRAN(FK7->FK7_CHAVE, "|", "")))
        If FK7->(!EoF())
            RecLock("FK7")
            FK7->(DbDelete())
            FK7->(MsUnLock())
        EndIf
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Atualiza sequencia dos movimentos da SE5
---------------------------------------------------------------------
/*/
Static Function SeqRecord(cSeq As Character)

    DEFAULT cSeq := ""
 
    If SE5->(!EoF())
        RecLock("SE5",.F.)
        SE5->E5_SEQ    := cSeq
        SE5->(MsUnlock())
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Verifica se existe movimentos complementares
---------------------------------------------------------------------
/*/
Static Function ChkMovCompl(cSeq As Character)
 
    Local aTipoDoc As Array
 
    Default cSeq := SE5->E5_SEQ
 
    aTipoDoc := {}
 
    DO CASE
        CASE SE5->E5_VLJUROS > 0
            aAdd(aTipoDoc,"JR")
 
        CASE SE5->E5_VLMULTA > 0
            aAdd(aTipoDoc,"MT")
 
        CASE SE5->E5_VLCORRE > 0
            aAdd(aTipoDoc,"CM")
    ENDCASE
         
    If !Empty(aTipoDoc)
        AtuMovCompl(aTipoDoc,cSeq)
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Atualiza os movimentos complementares
---------------------------------------------------------------------
/*/
Static Function AtuMovCompl(aTipoDoc As Array, cSeq As Character)
 
    Local aArea     As Array
    Local cChvParc1 As Character
    Local cChvParc2 As Character
    Local cData     As Character
    Local cIdOrig   As Character
    Local cFil      As Character
    Local nX        As Numeric
 
    Default aTipoDoc := {}
    Default cSeq     := SE5->E5_SEQ
 
    cChvParc1   := SE5->(E5_PREFIXO + E5_NUMERO + E5_PARCELA + E5_TIPO)
    cChvParc2   := SE5->(E5_CLIFOR + E5_LOJA)
    cData       := DTOS(SE5->E5_DATA)
    cIdOrig     := SE5->E5_IDORIG
    cFil        := SE5->E5_FILIAL
    nX          := 1
 
    aArea := SE5->(GetArea())
 
    SE5->(dbSetOrder(2))
    For nX := 1 to Len(aTipoDoc)
        If SE5->(dbSeek(cFil+aTipoDoc[nX]+cChvParc1+cData+cChvParc2))
            If SE5->E5_IDORIG == cIdOrig
                SeqRecord(cSeq)
                CleanSE5() 
            Endif
        EndIf
    Next nX
 
    RestArea(aArea)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Limpa referencias das FKs na SE5 dos Movimentos Complementares
---------------------------------------------------------------------
/*/
Static Function CleanSE5()
 
    Local aArea As Array
 
    aArea := SE5->(GetArea())

    If SE5->(!EoF())
        RecLock("SE5",.F.)
        SE5->E5_IDORIG := ""
        SE5->E5_TABORI := ""
        SE5->E5_MOVFKS := ""
        SE5->(MsUnlock())
    Else
        RestArea(aArea)
    EndIf
 
Return Nil

/*/
---------------------------------------------------------------------
    Verifica se existe ja inconsistencias nas gravacoes da compensacao
---------------------------------------------------------------------
/*/
Static Function VerErroGrv(cChvCmp As Character, cFilCmp As Character, SeqCmp As Character, nQtdCmp As Numeric, aCmpBa As Array, aCmpCp As Array, nQtdComp As Numeric) As Logical

    Local nQtdReal  As Numeric
    Local nDifCmp   As Numeric
    Local lRet      As Logical
    Local cDocumen  As Character
    Local aAreaSE5  As Array
    Local nPos      As Numeric

    Default cChvCmp  := ""
    Default cFilCmp  := ""
    Default SeqCmp   := ""
    Default nQtdCmp  := 0
    Default aCmpBa   := {}
    Default aCmpCp   := {}
    Default nQtdComp := E5TRB->QTDCMP

    nQtdReal := 0
    nDifCmp  := 0
    nPos     := 0
    lRet     := .F.
    cDocumen := ""
    aAreaSE5 := SE5->(GetArea())

    If SE5->E5_TIPODOC $ "BA"
        nQtdReal := ValiCmp(cChvCmp, cFilCmp, SeqCmp)

        If nQtdCmp <> nQtdReal
            nDifCmp := IIF(nQtdCmp > nQtdReal, nQtdCmp - nQtdReal, nQtdReal - nQtdCmp )

            If nDifCmp <> CmpParOk() //Valida se a cmp foi realizada na filial correta
                AAdd(aCmpCp, E5TRB->(E5_DOCUMEN))
                lRet := .T.
            Else    
                nQtdComp++
            EndIF
            
        ElseIf !Empty(aCmpCp)

            cDocumen := RTrim(SE5->E5_DOCUMEN)
    
			nPos := ASCAN(aCmpCp, { |x| x == cDocumen })
			If nPos > 0
				lRet := .T.
			EndIf
        Endif
    Else
        cDocumen := RTrim(SE5->E5_DOCUMEN)

        nPos := ASCAN(aCmpCp, { |x| RTrim(x) == cChvCmp })
        If nPos > 0
            lRet := .T.
        ElseIf  !Empty(aCmpBa)
			nPos := ASCAN(aCmpBa, { |x| x == cDocumen })
			If nPos == 0
				lRet := .T.
			EndIf
		Else
            lRet := .T.
        Endif
    EndIf

    RestArea(aAreaSE5)

Return lRet

/*/
---------------------------------------------------------------------
    Verifica se os dados referente a sequencia pode ser processados
---------------------------------------------------------------------
/*/
Static Function ValiCmp(cChvCmp As Character, cFilCmp As Character, SeqCmp As Character) As Numeric

    Local aAreaAnt as Array
	Local cQuery   as Character
    Local nQtdSeq  as Numeric
	
	Default cChvCmp := ""
    Default cFilCmp := ""
    Default SeqCmp  := ""

	aAreaAnt := GETAREA()
	cQuery   := ""
    nQtdSeq  := 0
 
    If _ValidCmp == Nil
		cQuery := " SELECT COUNT(E5_NUMERO) QTDREC FROM " + RetSqlName("SE5")
        cQuery += " WHERE"
        cQuery += " E5_FILIAL = ? AND "
        cQuery += " E5_DOCUMEN = ? AND "
        cQuery += " E5_SEQ = ? AND "
        cQuery += " E5_RECPAG = 'P' AND E5_TIPODOC <> 'ES' AND "
        cQuery += " D_E_L_E_T_ = ' ' "

		cQuery := ChangeQuery(cQuery)
		_ValidCmp := FWPreparedStatement():New(cQuery)
	EndIF	

	_ValidCmp:SetString(1,cFilCmp)
	_ValidCmp:SetString(2,cChvCmp)
    _ValidCmp:SetString(3,SeqCmp)

	cQuery := _ValidCmp:GetFixQuery()
	nQtdSeq := MpSysExecScalar(cQuery,"QTDREC")

    RESTAREA(aAreaAnt)

Return nQtdSeq


/*/
---------------------------------------------------------------------
    Verifica se ocorreu a compensacao com os mesmos titulos
---------------------------------------------------------------------
/*/
Static Function VerMsmChv(nRecSE5 As Numeric) As Logical

    Local aAreaAnt as Array
	Local cQuery   as Character
    Local lRet     as Logical
    Local cDocumen as Character
    Local cTbMsmCh as Character 
	
	Default nRecSE5 := (SE5->(RECNO()))

	aAreaAnt := SE5->(GETAREA())
	cQuery   := ""
    cDocumen := ""
    lRet     := .T.
    cTbMsmCh := ""

    SE5->(dbGoTo(nRecSE5))
 
    If _VldMsmChv == Nil
		cQuery := " SELECT R_E_C_N_O_ RECNO FROM " + RetSqlName("SE5")
        cQuery += " WHERE"
        cQuery += " E5_FILIAL = ? AND "
        cQuery += " E5_PREFIXO = ? AND "
        cQuery += " E5_NUMERO = ? AND "
        cQuery += " E5_PARCELA = ? AND "
        cQuery += " E5_TIPO = ? AND "
        cQuery += " E5_CLIFOR = ? AND "
        cQuery += " E5_LOJA = ? AND "
        cQuery += " E5_SEQ = ? AND "
        cQuery += " E5_RECPAG = 'P' AND E5_TIPODOC <> 'ES' AND "
        cQuery += " E5_MOTBX = 'CMP' AND "
        cQuery += " D_E_L_E_T_ = ' ' "

		cQuery := ChangeQuery(cQuery)
		_VldMsmChv := FWPreparedStatement():New(cQuery)
	EndIF	

	_VldMsmChv:SetString(1,SE5->E5_FILIAL)
	_VldMsmChv:SetString(2,SE5->E5_PREFIXO)
    _VldMsmChv:SetString(3,SE5->E5_NUMERO)
    _VldMsmChv:SetString(4,SE5->E5_PARCELA)
    _VldMsmChv:SetString(5,SE5->E5_TIPO)
    _VldMsmChv:SetString(6,SE5->E5_CLIFOR)
    _VldMsmChv:SetString(7,SE5->E5_LOJA)
    _VldMsmChv:SetString(8,SE5->E5_SEQ)

	cQuery := _VldMsmChv:GetFixQuery()
    cTbMsmCh := MpSysOpenQuery(cQuery)
    
	While (cTbMsmCh)->(!Eof())
        SE5->(dbGoTo((cTbMsmCh)->RECNO))
        
        If Empty(cDocumen)
            cDocumen := RTrim(SE5->E5_DOCUMEN)
        ElseIf RTrim(SE5->E5_DOCUMEN) <> cDocumen
            lRet := .F.
            Exit
        EndIf

        (cTbMsmCh)->(dbSkip())
    Enddo

    (cTbMsmCh)->(dbCloseArea())
     
    RESTAREA(aAreaAnt)

Return lRet


/*/
---------------------------------------------------------------------
    Verifica se ouve compensasoes parcialmente corretas
---------------------------------------------------------------------
/*/
Static Function CmpParOk() As Numeric

    Local aAreaAnt as Array
	Local cQuery   as Character
    Local nQtdOK  as Numeric
	
	aAreaAnt := GETAREA()
	cQuery   := ""
    nQtdOK  := 0
 
    If _CmpParcOk == Nil
		cQuery := " SELECT COUNT(E5_NUMERO) QTDOK " 
        cQuery += " FROM "+ RetSqlName("SE5") +" SE5 "
        cQuery +=   "INNER JOIN "+ RetSqlName("FK2") +" FK2 "
        cQuery +=       "ON FK2.FK2_FILIAL = SE5.E5_FILIAL AND "
        cQuery +=           "FK2.FK2_IDFK2 = SE5.E5_IDORIG "
        cQuery +=    "INNER JOIN "+ RetSqlName("FK7") +" FK7 "
        cQuery +=       "ON FK2.FK2_FILIAL <> FK7.FK7_FILIAL AND "
        cQuery +=           "FK2.FK2_IDDOC = FK7.FK7_IDDOC "
        cQuery += "WHERE FK2.FK2_FILORI = FK7.FK7_FILIAL AND FK2.FK2_MOTBX = 'CMP' AND "
        cQuery += "FK2.FK2_RECPAG = 'P' AND FK2.FK2_TPDOC <> 'ES' AND "
        cQuery += " E5_FILIAL = ? AND "
        cQuery += " E5_PREFIXO = ? AND "
        cQuery += " E5_NUMERO = ? AND "
        cQuery += " E5_PARCELA = ? AND "
        cQuery += " E5_TIPO = ? AND "
        cQuery += " E5_CLIFOR = ? AND "
        cQuery += " E5_LOJA = ? AND "
        cQuery += " E5_SEQ = ? AND "
        cQuery += "SE5.D_E_L_E_T_ = ' ' AND "
        cQuery += "FK2.D_E_L_E_T_ = ' ' AND "
        cQuery += "FK7.D_E_L_E_T_ = ' '"

		cQuery := ChangeQuery(cQuery)
		_CmpParcOk := FWPreparedStatement():New(cQuery)
	EndIF	

	_CmpParcOk:SetString(1,SE5->E5_FILIAL)
	_CmpParcOk:SetString(2,SE5->E5_PREFIXO)
    _CmpParcOk:SetString(3,SE5->E5_NUMERO)
    _CmpParcOk:SetString(4,SE5->E5_PARCELA)
    _CmpParcOk:SetString(5,SE5->E5_TIPO)
    _CmpParcOk:SetString(6,SE5->E5_CLIFOR)
    _CmpParcOk:SetString(7,SE5->E5_LOJA)
    _CmpParcOk:SetString(8,SE5->E5_SEQ)

	cQuery := _CmpParcOk:GetFixQuery()
	nQtdOK := MpSysExecScalar(cQuery,"QTDOK")

    RESTAREA(aAreaAnt)

Return nQtdOK

/*/
---------------------------------------------------------------------
    Deleta os Statements temporarios
---------------------------------------------------------------------
/*/
Static Function DelTmps(oTmp As Object)

    DEFAULT oTmp := Nil
 
    If oTmp != NIL
        oTmp:Destroy()
        oTmp := NIL
    Endif
 
Return Nil
/*/
---------------------------------------------------------------------
    Monta tela para selecao do grupo de empresas
---------------------------------------------------------------------
/*/
Static Function SelCompany() As Array
 
    Local aRet     As Array
    Local oDlg     As Object
    Local oGrpEmp  As Object
    Local oFilial  As Object
    Local oSay     As Object
    Local cEmp     As Character
    Local cFil     As Character
 
    aRet     := {}
    cEmp     := "  "
    cFil     := "        "
 
    Define MSDialog  oDlg Title "FA340FIX" From 0, 0 To 170, 326 Pixel
 
    oDlg:cToolTip := "Definicao do grupo de empresas que sera processado"
    oDlg:cTitle   := "Inicializacao do ambiente"
 
    @ 14, 37 Say  oSay Prompt "Informe o codigo do grupo de empresa" Size  55, 20 Of oDlg Pixel
    @ 16, 91 MSGet  oGrpEmp Var  cEmp Size  05, 05 Of oDlg Pixel Picture "@!"
 
    @ 34, 37 Say  oSay Prompt "Informe uma filial deste grupo de empresas" Size  55, 20 Of oDlg Pixel
    @ 36, 94 MSGet  oFilial Var  cFil Size  05, 05 Of oDlg Pixel Picture "@!"
 
    Define SButton From 63, 73 Type 1 Action ( oDlg:End() ) OnStop "Confirma"  Enable Of oDlg
    Activate MSDialog  oDlg Center
 
    Aadd(aRet,cEmp)
    Aadd(aRet,AllTrim(cFil))
 
Return aRet



03. TABELAS UTILIZADAS

Este Rdmake realiza a correção nas tabelas SE5, FKA, FK2, FK6, FK7 e SE2 nos cenários descritos no tópico "Exemplo de utilização".