Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.


ÍNDICE

Índice
excludeÍNDICE
stylenone
  1. Visión general
  2. Ejemplo de utilización
  3. Tablas utilizadas


01. VISIÓN GENERAL

Durante el proceso de compensación en sucursales diferentes de la sucursal de los títulos, se realizaba una grabación incorrecta en la tabla FK7 (antes de Septiembre de 2020). Esta grabación acaba impactando en la secuencia de baja de los títulos involucrados, impidiendo que se realice la reversión correctamente.

...

02. EJEMPLO DE UTILIZACIÓN

Card documentos
Informacao

...

El Rdmake se realizó por medio del problema informado en la issue mencionada en "Visión general", poniéndose a disposición la corrección únicamente para este escenario. Si se encuentran otros escenarios, la función de usuario esta disponible en esta documentación para personalización.
Titulo¡IMPORTANTE

...

!


Cómo utilizar:

       1 - Realice una copia de seguridad de la base de datos 

...

Bloco de código
languagejava
themeMidnight
titleCódigo fontefuente:
collapsetrue
Código fuente:  
#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
Corrección de las secuencias de las compensaciones que se realizaron en una
sucursalSucursal diferente de la sucursal de los títulos
 
@since  14/08/2020
@version 12
/*/
//--------------------------------------------------------------------------
User Function FA340FIX()
 
	    Local aSay      As Array
	    Local aButton   As Array
	    Local aEmp	    As  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   := "Corrección de base - Compensación CP"
	    cDesc1    := "Este programa corregirá las secuencias de la Compensación CP. "
	    cDesc2    := "Este proceso debe ejecutarse en modo EXCLUSIVO, es decir, no puedepueden haber otros        "
	    cDesc3    := "  usuarios  o  jobs utilizandoque utilizan el Financiero.  Es muyextremadamente recomendable recomendabel que  se  haga una"
	    cDesc4    := "  COPIA DE SEGURIDAD de la  BASE DE DATOS antes de esta actualización.                   "
 
	    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
		    If lOk
        aEmp := {}
		        aEmp := SelCompany()

		 
        If !Empty( aEmp )
			            oProcess := MsNewProcess():New( { | lEnd | lOk := FA340Process(aEmp) }, "Actualizando", "Espere, actualizando...", .F. )
			            oProcess:Activate()

			 
            If lOk
				Conout(                 Conout("Actualización finalizada." )
			Else
				Conout( "Actualización no realizada            Else
                Conout("La actualización no se realizó." )
			EndIf
		EndIf
	EndIf
            EndIf
        EndIf
    EndIf
 
Return .T.
 
/*/
---------------------------------------------------------------------
    Reconstrucción de compensaciones 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

	RpcSetType(3)

	RPCSetEnv(aEmp[1],aEmp[2], NIL, NIL, "FIN")

	    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	    lRet      := .F.
	    cQuery    := ""
	cIDAnt	    cIDAnt    := ""
	    lMigrador := .T.
	lEstFK6	    lEstFK6   := .F.
	cIDFK6	    cIDFK6    := ""
	aEstFK6	    aEstFK6   := {}
    aCmpBa    := {}
    aCmpCp    := {} 
    lProcOk   := .T.
    lAntProc  := .F.
 
	    cQuery := "SELECT SE5.E5_VALOR, 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"	 // Cant. Compensaciones p/ título
	    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"	    // Cant. Reversiones de la 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     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_FILIALTIPODOC, SE5.E5_TIPODOCFILIAL, 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.

	// Abre copia de la __SE5 para caché del E5_IDORIG después del fkcommit en la ATUSEQ
	If Select("__SE5") == 0
		ChkFile("SE5",.F.,"__SE5")
	Else
		DbSelectArea("__SE5")
	EndIf

	While E5TRB->(!EOF())

		lMigrador 
    BEGIN TRANSACTION
        While E5TRB->(!EOF())
    
            lMigrador := .T.
            lEstFK6   := .T.
		lAtuEst            lAntProc  := .TF.
		lEstFK6            lProcOk   := .T.
		
		BEGIN TRANSACTION

			
            cChaveDoc := E5TRB->E5_DOCUMEN
			cChaveMov := E5TRB            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.
			EndIf

			cIDFK2Ant := FK2->FK2_IDFK2
			cIDAnt                 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                AAdd(aEstFK6,E5TRB->RECSE5)
			EndIf

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

			            EndIf

            SE5->(dbGoTo(E5TRB->RECSE5))
			__SE5->(dbGoTo(SE5->(Recno())))

			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(            
            If lFirst .Or. !lAntProc
                If VerErroGrv(cChaveMov, E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov)

						SE5->(dbGoTop())	// Solamente para actualizar workarea
						SE5->(dbGoTo(E5TRB->RECSE5))

					EndIf

					If E5TRB->QTDEST > 0
						FixES(E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov, @aEstFK6) // Buscar y arregla reversiones inconsistentes
					EndIf
				EndIf
			Else	
				lMigrador SE5->E5_SEQ, E5TRB->QTDCMP, aCmpBa, @aCmpCp, @nQtdComp) //Verifica inconsistencia
                    lProcOk := .F.
			   
                EndIf

		END TRANSACTION	// Finaliza la transacción para realizar el commit en las actualizaciones antes de ejecutar el migrador

		If lMigrador
			BEGIN TRANSACTION
				FnBaixaE2(E5TRB->RECSE5,E5TRB->E5_FILORIG)
			END TRANSACTION

			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

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

            If !lProcOk // No procesa si tiene errores
                E5TRB->(dbSkip())

		If lFirst
			lRet := .T.
			lFirst := .F.
		EndIf

	EndDo

	If !Empty(aEstFK6)
		AtuEsCm(aEstFK6)
	EndIf
	
	aSize(_aRecCM,0)
	_aRecCM := NIL
	DelTmps(_oSeqAtu)
	DelTmps(_oTmpEST)

	RestArea(aAreaAnt)

Return lRet 

/*/
----------------------------------------------------------------------
    Actualiza las reversiones de correcciones 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

/*/
----------------------------------------------------------------------
    Encuentra las reversiones incorrectas de las compensaciones para rehacerlas
----------------------------------------------------------------------
/*/
Static Function FixES(cFil As Character, cDoc As Character, cChave As Character, aEstFK6 As Array) As Logical

	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

	Default cFil 	  := ""
	Default cDoc	  := ""
	Default cChave    := ""
	Default aEstFK6	  := {}

	aAreaAnt := GetArea()
	aAreaSE5 := SE5->(GetArea())
	nValor	 := 0
	nValorE5 := 0

	BEGIN SEQUENCE

		If E5TRB->QTDCMP > 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	// Si el valor fue diferente, sabemos que la pierna de la reversión está equivocada
						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,"-") // Deshace reversión incorrecta de la compensación
						FixSE5("FIXES",aAreaSE5)	// Corrige pierna de reversión en la SE5
						If FK2->(dbSeek(cFil+cIDFK2))	// Borra 1a pierna de la reversión en la FK2
							CleanFK2()
						EndIf
						If FK2->(dbSeek(cFil+FIXES->E5_IDORIG))	// Borra en la 2a pierna de la reversión en la FK2
							CleanFK2()
						EndIf
						
						FixSE2("SE5",FIXES->E5_FILORIG,FIXES->E5_DOCUMEN,"+")
					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.;	// Si el valor fuera diferente, sabemos que es la pierna equivocada de la reversión
						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

					FixSE2("FIXES",SE5->E5_FILORIG,SE5->E5_DOCUMEN,"-") // Deshace la reversión incorrecta de la compensación
					FixSE5("SE5",aAreaSE5)	// Corrige la pierna de la reversión en la SE5
					If FK2->(dbSeek(cFil+cIDFK2))	// Borrar la pierna de la reversión en la FK2
						CleanFK2()
					EndIf
					If FK2->(dbSeek(cFil+SE5->E5_IDORIG))	// Borra la 2ª pierna de la reversión en la FK2
						CleanFK2()
					EndIf
					FixSE2("SE5",SE5->E5_FILORIG,SE5->E5_DOCUMEN,"+")
				EndIf
				FIXES->(dbSkip())
			EndDo
			If nValor <> 0
				SE5->(dbClearFilter())
			EndIf
		EndIf

		FIXES->(dbCloseArea())

	END SEQUENCE

	RestArea(aAreaAnt)

	RestArea(aAreaSE5)

Return Nil
                Loop 
            EndIf

            If lAntProc // No procesa el mismo título
                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

                        //Actualiza secuencias de la SE5
                        ATUSEQ(E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov,nQtdComp)

                        SE5->(dbGoTop()) // Solamente para actualizar workarea
                        SE5->(dbGoTo(E5TRB->RECSE5))

                    EndIf

                    If E5TRB->QTDEST > 0
                        FixES(E5TRB->FK2_FILIAL,cChaveDoc,cChaveMov,@aEstFK6,nQtdComp) // Busca y arregla reversiones 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
 
/*/
----------------------------------------------------------------------
    Actualiza las reversiones de correcciones 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
 
/*/
----------------------------------------------------------------------
    DeshaceEncuentra las lareversiones compensaciónincorrectas ende loslas tituloscompensaciones para rehacer despuésrehacerlas
----------------------------------------------------------------------
/*/
Static Function FixSE2FixES(cAliascFil As Character, cFilcDoc As Character, cChave As Character,cOper, aEstFK6 As Array, nQtdComp As CharacterNumeric)
 
    Local aAreaAnt   As Array
    Local nSaldo aAreaSE5   As NumericArray

	Default cAlias   := "SE5"

Local cQuery    aAreaAnt := GetArea()

As Character
    SE2->(dbSetOrder(1))
 Local cIDFK2   If SE2->(dbSeek(cFil+RTrim(cChave))) .and. !Empty(SE2->E2_BAIXA)  // Verifica si el título ya se reconstituyó
   As Character
    Local cCposChave As Character
    Local nValor      SA2->(dbSetOrder(1))As Numeric
    Local nValorE5   SA2->(dbSeek(xFilial("SA2",SE2->E2_FILORIG)+SE2->(E2_FORNECE+E2_LOJA)))
As Numeric
    Local nValBA    nSaldo := MontaSaldo(cAlias)
		RecLock("SE2",.F.)
		If cOper == "-"	// Sustrae, deshaciendo la reversión incorrecta
			SE2->E2_SALDOAs Numeric
 
    Default cFil      := ""
    Default cDoc      -:= nSaldo
			SE2->E2_SDACRES""
    -= (cAlias)->E5_VLACRES
			SE2->E2_SDDECREDefault cChave    -:= (cAlias)->E5_VLDECRE
		Else	// Suma, rehaciendo la reversión correcta
			SE2->E2_SALDO     += nSaldo
			SE2->E2_SDACRES   += (cAlias)->E5_VLACRES
			SE2->E2_SDDECRE   += (cAlias)->E5_VLDECRE
		EndIf
        MsUnlock()
    EndIf
    RestArea(aAreaAnt)

Return Nil

/*/
---------------------------------------------------------------------
    Corrige las reversiones de compensaciones en la 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 Sec. Actualizada
	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  //En casos de moneda extranjero se invierten los 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())
		CleanSE5()

		SE5->(DbSetOrder(7))
		If SE5->(dbSeek(SE5->E5_FILIAL + Rtrim(cChave)))
			SeqRecord(cSeq)	// Actualiza la reversión
			CleanSE5()
		EndIf
	EndIf

	RestArea(aAreaAnt)

Return 

/*/
---------------------------------------------------------------------
    Recompone el saldo de los títulos revertidos incorrectamente
---------------------------------------------------------------------
/*/
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

/*/
---------------------------------------------------------------------
    Actualiza secuencias de compensaciones en la SE5
---------------------------------------------------------------------
/*/
Static Function ATUSEQ(cFil As Character, cDoc As Character, cChave As Character)
	Local aAreaAnt  As Array
	Local cChavePai As Character
	Local cSeqPAI 	As Character
	Local cDocPAI	As Character
	Local lMultSeq 	As Logical
	Local cCountSeq	As Character
	Local cNewSeq 	As Character
	Local lRet		As Logical
	Local lFlush 	As Logical
	Local nBxParc	As Numeric
	Local cQuery 	As Character
	Local aAreaSE5  As Array

	Default cFil 	  := ""
	Default cDoc	  := ""
	Default cChave    := ""

	aAreaAnt   := GetArea()
	aAreaSE5   := SE5->(GetArea())
	cDocPAI	   := Alltrim(SE5->(E5_FILIAL+E5_DOCUMEN))
	lMultSeq   := lRet := lFlush := .F.
	cCountSeq  := cSeqPAI := SE5->E5_SEQ
	cNewSeq    := cQuery := ""	
	nBxParc    := 1
	cDocNf	   := ""

	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(E5TRB->QTDCMP > 1,cChave,RTrim(cDoc)))

	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)

		//Actualiza secuencia del título de destino
		SeqRecord(cCountSeq)
		ChkMovCompl(cCountSeq)
		CleanSE5()

		cDocNf := RTrim(SE5->E5_DOCUMEN)
		
		dbSelectArea("SE5")
		SET FILTER TO SE5->E5_FILIAL == cFil .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())

		//Actualiza secuencia del título de partida
		SeqRecord(cCountSeq)
		ChkMovCompl(cCountSeq)
		CleanSE5()
		SE5->(dbClearFilter())

		E5SEQ->(dbSkip())
	EndDo	
	
	If lFlush
		SE5->(FKCommit())
	EndIf
	
	RestArea(aAreaSE5)
	RestArea(aAreaAnt)

Return Nil

/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FKA
---------------------------------------------------------------------
/*/
Static Function CleanFKA()

	If FKA->(!EoF())	
		RecLock("FKA")
		FKA->(DbDelete())
		FKA->(MsUnLock())
	EndIf

Return Nil

/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK2
---------------------------------------------------------------------
/*/
Static Function CleanFK2()

	If FK2->(!EoF())	
		RecLock("FK2")
		FK2->(DbDelete())
		FK2->(MsUnLock())
	EndIf

Return Nil

/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK3 y 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

/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK6
---------------------------------------------------------------------
/*/
Static Function AtuFK6(cIDFK2 As Character, cFK2Atu As Character, lEstFK6)

	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

/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK7
---------------------------------------------------------------------
/*/
Static Function CleanFK7()

	If !SE2->(dbSeek(STRTRAN(FK7->FK7_CHAVE, "|", "")))
		If FK7->(!EoF())	
			RecLock("FK7")
			FK7->(DbDelete())
			FK7->(MsUnLock())
		EndIf
	EndIf

Return Nil

/*/
---------------------------------------------------------------------
    Actualiza secuencia de los movimientos de la SE5
---------------------------------------------------------------------
/*/
Static Function SeqRecord(cSeq As Character)

	If SE5->(!EoF())	
		RecLock("SE5",.F.)
		SE5->E5_SEQ    := cSeq
		SE5->(MsUnlock())

		//FlagMov()
	EndIf

Return Nil

/*/
---------------------------------------------------------------------
    Verifica si existe movimientos complementarios
---------------------------------------------------------------------
/*/
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

/*/
---------------------------------------------------------------------
    Actualiza los movimientos complementarios
---------------------------------------------------------------------
/*/
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

/*/
---------------------------------------------------------------------
    Limpia referencias de las FK en la SE5 para ejecutar el migrador
---------------------------------------------------------------------
/*/
Static Function CleanSE5()

	Local aArea As Array

	aArea := __SE5->(GetArea())
	__SE5->(dbGoTo(SE5->(Recno())))

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

Return Nil""
    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 // Si el valor fuera diferente, sabemos que es la parte equivocada de la reversión
                        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,»-») // Deshace reversión incorrecta de la compensación
                        FixSE5(«FIXES»,aAreaSE5)    // Corrige parte de la reversión en la SE5
                        If FK2->(dbSeek(cFil+cIDFK2))    // Borra la lra. parte de la reversión en la FK2
                            CleanFK2()
                        EndIf
                        If FK2->(dbSeek(cFil+FIXES->E5_IDORIG))   // Borra la 2da. parte de la reversión en la 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.;   // Si el valor fuera diferente, sabemos que es la parte equivocada de la reversión
                        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,»-») // Deshace reversión incorrecta de la compensación
                            FixSE5(«SE5»,aAreaSE5)  // Corrige parte de la reversión en la SE5
                            If FK2->(dbSeek(cFil+cIDFK2))    // Borra la lra. parte de la reversión en la FK2
                                CleanFK2()
                            EndIf
                            If FK2->(dbSeek(cFil+SE5->E5_IDORIG)) // Borra la 2da. parte de la reversión en la 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
 
/*/
---------------------------------------------------------------------
    Deshace la compensación en los títulos para rehacer después
---------------------------------------------------------------------
/*/
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 si el título ya se reconstituyó
        SA2->(dbSetOrder(1))
        SA2->(dbSeek(xFilial("SA2",SE2->E2_FILORIG)+SE2->(E2_FORNECE+E2_LOJA)))
        nSaldo := MontaSaldo(cAlias)
        RecLock("SE2",.F.)
        If cOper == «-» // Sustrae, deshaciendo la reversión incorrecta
            SE2->E2_SALDO     -= nSaldo
            SE2->E2_SDACRES   -= (cAlias)->E5_VLACRES
            SE2->E2_SDDECRE   -= (cAlias)->E5_VLDECRE
        Else    // Suma, rehaciendo la reversión correcta
            SE2->E2_SALDO     += nSaldo
            SE2->E2_SDACRES   += (cAlias)->E5_VLACRES
            SE2->E2_SDDECRE   += (cAlias)->E5_VLDECRE
        EndIf
        MsUnlock()
    EndIf
    RestArea(aAreaAnt)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Corrige las reversiones de compensaciones en la 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  // Copia Sec. Actualizada
    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  //En los casos de moneda extranjera, se invierten los 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) // Actualiza reversión
        EndIf
    EndIf
 
    RestArea(aAreaAnt)
 
Return
 
/*/
---------------------------------------------------------------------
    Recompone el saldo de los títulos revertidos incorrectamente
---------------------------------------------------------------------
/*/
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
 
/*/
---------------------------------------------------------------------
    Actualiza secuencias de compensaciones en la 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)
 
        //Actualiza secuencia del título 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())
 
        //Actualiza secuencia del título de partida
        SeqRecord(cCountSeq)
        ChkMovCompl(cCountSeq)

        SE5->(dbClearFilter())
 
        E5SEQ->(dbSkip())
    EndDo  
     
    If lFlush
        SE5->(FKCommit())
    EndIf
     
    RestArea(aAreaSE5)
    RestArea(aAreaAnt)
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FKA
---------------------------------------------------------------------
/*/
Static Function CleanFKA()
 
    If FKA->(!EoF())
        RecLock("FKA")
        FKA->(DbDelete())
        FKA->(MsUnLock())
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK2
---------------------------------------------------------------------
/*/
Static Function CleanFK2()
 
    If FK2->(!EoF())
        RecLock("FK2")
        FK2->(DbDelete())
        FK2->(MsUnLock())
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK3 y 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
 
/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la 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
 
/*/
---------------------------------------------------------------------
    Borra referencias incorrectas de la FK7
---------------------------------------------------------------------
/*/
Static Function CleanFK7()
 
    If !SE2->(dbSeek(STRTRAN(FK7->FK7_CHAVE, "|", "")))
        If FK7->(!EoF())
            RecLock("FK7")
            FK7->(DbDelete())
            FK7->(MsUnLock())
        EndIf
    EndIf
 
Return Nil
 
/*/
---------------------------------------------------------------------
    Actualiza secuencia de los movimientos de la 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 si existe movimientos complementarios
---------------------------------------------------------------------
/*/
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
 
/*/
---------------------------------------------------------------------
    Actualiza los movimientos complementarios
---------------------------------------------------------------------
/*/
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
 
/*/
---------------------------------------------------------------------
    Limpia referencias de las FK en la SE5 de los movimientos complementarios
---------------------------------------------------------------------
/*/
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 si existen inconsistencias en las grabaciones de la compensación
---------------------------------------------------------------------
/*/
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 si la cmp se realizó en la sucursal correcta
                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 si los datos referentes a la secuencia pueden procesarse
---------------------------------------------------------------------
/*/
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 si ocurrió la compensación con los mismos títulos
---------------------------------------------------------------------
/*/
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 si hubo compensaciones parcialmente correctas
---------------------------------------------------------------------
/*/
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

/*/
---------------------------------------------------------------------
    Borra los Statements temporales
---------------------------------------------------------------------
/*/
Static Function DelTmps(oTmp As Object)

	    DEFAULT oTmp := Nil
 
    If oTmp != NIL
		        oTmp:Destroy()
		        oTmp := NIL
	    Endif
 
Return Nil 
/*/
---------------------------------------------------------------------
    Elabora la pantalla para la selección del grupo de empresas
---------------------------------------------------------------------
/*/
Static Function SelCompany() As CharacterArray
 
	    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 	    cEmp     := "  "
	    cFil 	    := "        "
 
	    Define MSDialog  oDlg Title "FA340FIX" From 0, 0 To 170, 326 Pixel
 
	    oDlg:cToolTip := "Definición del grupo de empresas que se procesará"
	oDlg:cTitle   := "Inicialización del entorno"

	@ 14, 37 Say  oSay Prompt "Informe el código del grupo de empresa" Size  55, 20 Of oDlg Pixel
	@ 16, 91 MSGet  oGrpEmp Var  cEmp Size  05, 05 Of oDlg:cTitle Pixel  Picture:= "@!" 

	@ 34Inicialización del entorno"
 
    @ 14, 37 Say  oSay Prompt "Informe unael sucursalcódigo dedel este grupo de empresasempresa" Size  55, 20 Of oDlg Pixel
	    @ 3616, 9491 MSGet  oFilialoGrpEmp Var  cFilcEmp 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. TABLAS UTILIZADAS

Este Rdmake realiza la corrección en las tablas SE5, FKA, FK2, FK6, FK7 y SE2 en los escenarios descritos en el tópico "Ejemplo de utilización".

...

@ 34, 37 Say  oSay Prompt "Informe una sucursal de este 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. TABLAS UTILIZADAS

Este Rdmake realiza la corrección en las tablas SE5, FKA, FK2, FK6, FK7 y SE2 en los escenarios descritos en el tópico "Ejemplo de utilización".

...