01. VISIÓN GENERAL

Ejecución automática (ExecAuto) de la rutina de liquidación por cobrar (FINA460).

02. PARÁMETROS


Posición

Tipo

Nombre

Descripción

1

Numérico

nPosArotina

Se utiliza para indicar la operación que se ejecutará. Solamente se utiliza por la llamada de la rutina estándar por el menú. Enviar NIL o 0 (cero).

2

Vector

aAutoCab

Se utiliza para enviar datos referente al proceso, como:

  • Condición de pago (Si se envía, se graba en el encabezado de la liquidación, sin embargo la rutina no reprocesa ni valida el vector aAutoItens de acuerdo con la condición de pago, es decir, la personalización del cliente debe crear el vector aAutoItens de acuerdo con la condición y enviar a ExecAuto debidamente parametrizado - vea el ejemplo 1 de este documento).
  • Modalidad del título que se generará
  • Tipo del título que se generará
  • Cliente del título que se generará
  • Moneda del título que se generará
  • Tienda del cliente del título que se generará
  • Pix (default .T.)

3

Vector

aAutoItens

Vector utilizado para envío de los datos referentes a los títulos que se generarán, como:

  • Prefijo
  • Número del título
  • Cuota (Si no se envía, el sistema calculará automáticamente las cuotas de acuerdo con el parámetro MV_1DUP)
  • Banco
  • Agencia
  • Cuenta
  • Número del cheque (dará origen al número del título que se generará)
  • Emisor del cheque
  • Fecha de vencimiento del título
  • Valor del cheque/título
  • Valor del aumento (si hubiera)
  • Valor del descuento (si hubiera)
  • Valor adicional negociado: debe utilizarse la variable nValorJur.

Ejemplo:

Aadd(aItens,{;
{"E1_PREFIXO" ,'LIQ' },;
{'E1_NUM' , '300' },;
{'E1_PARCELA' , 'A' },;
{'E1_VENCTO' , STOD('20210215') },;
{'E1_VLCRUZ' , 1000.00 },;
{'nValorJur', 10}})

4

Numérico

nOpcAuto

Proceso que se desea realizar:
3 = Liquidación
4 = Reliquidación
5 = Anulación de liquidación

5

Carácter

cAutoFil

Expresión ADVPL para filtro de selección de los títulos generadores de la liquidación (que se liquidarán). Se utilizará si el parámetro cFilSQL no se informara.

Importante

Se recomienda el uso del filtro en SQL (cFilSQL - posición 13), pues el filtro en ADVPL está limitado a 2000 caracteres. Más información en: Filter greater than 2000 bytes

6

Carácter

cNumLiqCan

Número de la liquidación que se quiere anular. Solamente se envía si nOpcAuto = 5

7

Vector

aRotAutoVA

Vector utilizado para envío de los valores adicionales de los títulos que se generarán.

8

Numérico

nOutrMoed

Tratamiento para otras monedas (idéntico a la pantalla de filtro).

1 = Convierte
2 = No considera
3 = Variación monetaria

9

Numérico

nTxNegoc

Tasa de la moneda de la negociación.

Importante

Es obligatorio solamente para nOutrMoed = 3 - Variación monetaria. Se inicializa con la tasa del día de la negociación.

10

Numérico

nTpTaxa

Tipo de tasa de la negociación.

1=Fija
2=Variable

Importante

Es obligatorio solamente para nOutrMoed = 3 - Variación monetaria. Se inicializa con 2 - Variable.

11

Carácter

cFunOrig

El valor de esta variable se grabará en el campo E1_ORIGEM.

Importante

Si esta variable no se informara, se grabará la información de la función activadora de Execauto.

12

Numérico

nTxCalJur


13

Carácter

cFilSQL

Expresión SQL para filtro de selección de los títulos generadores de la liquidación (que se liquidarán). Sustituye el filtro en ADVPL (cAutoFil).

03. CONDICIÓN DE PAGO

1) Si se envía la condición de pago en el array aAutoCab
La personalización del cliente debe crear el array aAutoItens de acuerdo con la condición y enviar a execauto debidamente parametrizado. Debe utilizarse la función 'Condicao' para devolver la cantidad de de cuotas.

2) Si NO se envía la condición de pago en el array aAutoCab
La personalización del cliente debe crear el array aAutoItens manualmente y enviar a execauto debidamente parametrizado.

3) Si se envía(n) la(s) cuota(s) en el array aAutoItens
La rutina grabará esta información en el campo E1_PARCELA de los títulos generados.

4) Si NO se envía la cuota en el array aAutoItens
La rutina grabará el campo E1_PARCELA de los títulos generados de acuerdo con el parámetro MV_1DUP, DE FORMA secuencial.

04. EJEMPLO DE UTILIZACIÓN


Ejemplo 01 - Elaboración del vector aAutoItens de acuerdo con la condición de pago
#include "PROTHEUS.CH"

User Function UFINA460()
	Local cNum := ""
	Local nZ := 0
	Local aCab := {}
	Local aItens := {}
	Local nOpc := 3 //3-Liquidación,4-Reliquidación,5-Anulación de la liquidación
	Local cFiltro := ""
	Local cLiqCan := Space(6) //número de la liquidación que se anulará
	Local aParcelas := {}
	Local nValor := 2000 //Valor que se liquidará
	Local cCond := '001' //Condición de pago 1x
	Local nRadio := 1
	Local oRadio
	Local oLiqCan
    Local lAutoPix := .F.

	cNum := padr("200", tamSx3("E1_NUM")[1])

	//Pantalla utilizada solamente para ejemplo
	nOpca := 0
	DEFINE MSDIALOG oDlg FROM 094,1 TO 240,300 TITLE "Liquidación automática" PIXEL
	@ 010,010 Radio oRadio VAR nRadio;
	ITEMS "Liquidar",;
	"Reliquidar",;
	"Anular";
	3D SIZE 50,10 OF oDlg PIXEL ;
	ON CHANGE ( oLiqCan:lReadOnly := If(nRadio != 3, .T., .F.))

	@ 022,070 SAY "Cancel. Liquidación:" SIZE 49, 07 OF oDlg PIXEL
	@ 030,070 MSGET oLiqCan VAR cLiqCan Valid !Empty(cLiqCan) SIZE 49, 11 OF oDlg PIXEL hasbutton

	DEFINE SBUTTON FROM 55,085 TYPE 1 ENABLE OF oDlg ACTION ( nOpca := 1, oDlg:End())
	DEFINE SBUTTON FROM 55,115 TYPE 2 ENABLE OF oDlg ACTION ( nOpca := 0, oDlg:End())

	ACTIVATE MSDIALOG oDlg CENTERED

	If nOpca == 1
		If nRadio == 1 .or. nRadio == 2
			If nRadio == 1 //liquidación
				nOpc := 3
				//Filtro del usuario
				cFiltro := "E1_FILIAL == '"+xFilial("SE1") + "' .And. "
				cFiltro += "E1_CLIENTE == '000100' .And. E1_LOJA == '01' .And. "
				cFiltro += "E1_SITUACA $ '0FG' .And. E1_SALDO > 0 .and. "
				cFiltro += 'Empty(E1_NUMLIQ)'
			Else
				nOpc := 4 //reliquidación
				//Filtro del usuario
				cFiltro := "E1_FILIAL == '"+xFilial("SE1") + "' .And. "
				cFiltro += "E1_CLIENTE == '000100' .And. E1_LOJA == '01' .And. "
				cFiltro += "E1_SITUACA $ '0FG' .And. E1_SALDO > 0 .and. "
				cFiltro += '!Empty(E1_NUMLIQ)'
			Endif

			//Array del proceso automático (aAutoCab)
			aCab := { {"cCondicao" ,cCond },;
			{"cNatureza" ,"001" },;
			{"E1_TIPO" ,"NF " },;
			{"cCLIENTE" ,"000100"},;
			{"nMoeda" ,1 },;
			{"cLOJA" ,"01" },;
            {"AUTMRKPIX", lAutoPix }} 
            //------------------------------------------------------------
			//Elabora las cuotas de acuerdo con la condición de pago
			//------------------------------------------------------------
			aParcelas := Condición( nValor, cCond,, dDataBase)

			//--------------------------------------------------------------
			//No es posible enviar Aumento y Descuento juntos.
			//Si se envían los dos valores mayores que cero, considera Aumento
			//--------------------------------------------------------------
			For nZ := 1 to Len(aParcelas)
				//Datos de las cuotas que se generarán
				Aadd(aItens,{{ "E1_PREFIXO", "LIQ" },; //Prefijo
				{"E1_BCOCHQ" , "CX1" },; //Banco
				{"E1_AGECHQ" , "00001" },; //Agencia
				{"E1_CTACHQ" , "0000000001" },; //Cuenta
				{"E1_NUM" , cNum },; //Nº Cheque (dará origen al número del título)
				{"E1_EMITCHQ" , "EXECAUTO" },; //Emisor del cheque
				{"E1_VENCTO" , aParcelas[nZ,1]},; //Fecha buena
				{"E1_VLCRUZ" , aParcelas[nZ,2]},; //Valor del cheque/título
				{"E1_ACRESC" , 0 },; //Aumento
				{"E1_DECRESC" , 0 }}) //Descuento

				cNum := Soma1(cNum, Len( Alltrim(cNum)))
			Next nZ

			If Len( aParcelas) > 0
				//Liquidación y reliquidación
				//FINA460(nPosArotina,aAutoCab,aAutoItens,nOpcAuto,cAutoFil,cNumLiqCan)
				FINA460(, aCab, aItens, nOpc, cFiltro) //Inclusión

				// Este aviso solamente funciona para prueba monousuario
				Alert("Liquidación incluida -> " + GetMv("MV_NUMLIQ"))
			Endif
		Else
			nOpc := 5
			//Anulación
			FINA460(,,, nOpc,, cLiqCan) //Anulación
			Alert("Liquidación anulada -> " + cLiqCan)
		Endif
	EndIf

Return
  



Ejemplo 02 - Elaboración del vector aAutoItens manualmente, sin utilizar una condición de pago
#INCLUDE 'Protheus.ch'

User Function TST460()
	Local nX        :=  0
	Local aCab      :=  {}
	Local aItens    :=  {}
	Local cFilSQL	:=  ""  //filtro que contendrá los títulos que se liquidarán, generados con base en el array aTitOri
	Local aTitOri   :=  {}     
	Local cNaturez  :=  '000001'
	Local nMoeda    :=  1
	Local cTipoLiq  :=  'FT '
	Local cCond     :=  ""

	local cLiqPref		:= 'FIN'
	local cLiqNum		:= '000000242'
	local cLiqParcela 	:= 'A'
	Local cLiqTipo 		:= "FT "
	local cLiqCli		:= '000001'
	local cLiqLoja		:= '01'
	local nValLiq		:= 2000
    Local lAutoPix := .F.

	Private lMsErroAuto     := .F.
	Private lAutoErrNoFile  := .T.
	
	Aadd(aTitOri,{'D MG 01 ', 'FIN', '000000001', 'A', 'NF ', '000001', '01'})
	Aadd(aTitOri,{'D MG 01 ', 'FIN', '000000001', 'B', 'NF ', '000001', '01'})

	Aadd(aItens,{{"E1_PREFIXO",cLiqPref}, {'E1_NUM', cLiqNum}, {'E1_PARCELA', cLiqParcela}, {'E1_VENCTO', dDatabase}, {'E1_VLCRUZ', nLiqVal}})	

	cFilSQL := " (" 
	For nX := 1 To Len(aTitOri)
		If nX > 1
			cFilSQL += " OR "
		EndIf 
		cFilSQL += " (" 
		cFilSQL += " E1_FILIAL  = '" + aTitOri[nX][1] + "' AND "
		cFilSQL += " E1_PREFIXO = '" + aTitOri[nX][2] + "' AND E1_NUM  = '" + aTitOri[nX][3] + "' AND "
		cFilSQL += " E1_PARCELA = '" + aTitOri[nX][4] + "' AND E1_TIPO = '" + aTitOri[nX][5] + "' AND "
		cFilSQL += " E1_CLIENTE = '" + aTitOri[nX][6] + "' AND E1_LOJA = '" + aTitOri[nX][7] + "' )"	
	Next nX
	cFilSQL += ") AND E1_SITUACA IN ('0','F','G') AND E1_SALDO > 0 AND LTRIM(E1_NUMLIQ) = '' "

	aCab := {}
	aAdd(aCab, {"cCondicao", 	cCond}) //Condición de pago
	aAdd(aCab, {"cNatureza", 	cNaturez}) //Modalidad
	aAdd(aCab, {"E1_TIPO", 		cLiqTipo}) //Tipo
	aAdd(aCab, {"cCliente", 	cLiqCli}) //Cliente
	aAdd(aCab, {"cLoja", 		cLiqLoja}) //Tienda
	aAdd(aCab, {"nMoeda",	 	nMoeda}) //Moneda
 	aAdd(aCab, {"AUTMRKPIX",    lAutoPix}) //Pix

	Fina460(/*nPosArotina*/,aCab,aItens,3,/*cFiltroADVPL*/,/*xNumLiq*/,/*xRotAutoVa*/,/*xOutMoe*/,/*xTxNeg*/,/*xTpTaxa*/,/*xFunOrig*/,/*xTxCalJur*/,cFilSQL)
Return

Ejemplo 03 - Manejo del valor del título que se liquidará
#Include "Protheus.ch"
#Include "rwmake.ch"
#Include "FWMVCDEF.ch"

Static nValTot      := 0
Static lCpoFK7      := Nil
Static FunName      := Nil
Static aIDDOC       := {}

User Function FINA460A()

Local aParam    := PARAMIXB
Local xRet      := .T.
Local oObj      := NIL
Local cIdPonto  := ''
Local cIdModel  := ''
Local nDescon   := 10
Local nI        := 0
Local cCli460   := ""
Local nValAux   := 0
Local nLenFO2   := 0
Local nValParc  := 0
Local nTxMul    := 10
Local nTxJur    := 1

If FunName == Nil
    FunName   := AllTrim(FunName())
EndIf

If FunName != "FINA460"
    If lCpoFK7 == Nil
        lCpoFK7   := FK7->(ColumnPos("FK7_CLIFOR")) > 0
    EndIf

    /*Tasa de interés" (FO1_TXJUR), "Tasa de la multa" (FO1_TXMUL), "Val. Descuento" (FO1_DESCON) y "Val.Adic.Neg" (FO1_VLADIC), */

    If aParam <> NIL
        oObj := aParam[1]

        cIdPonto := aParam[2]
        cIdModel := aParam[3]

        If cIdPonto == 'FORMLINEPOS'
            If cIdModel == 'TITSELFO1'
                cTit    := Marque( "FK7", 1, xFilial("FK7") + oObj:GetValue( "FO1_IDDOC" ), "FK7_NUM" )
                cCli460 := Marque( "FK7", 1, xFilial("FK7") + oObj:GetValue( "FO1_IDDOC" ), "FK7_CLIFOR" )
                If aScan( aIDDOC, oObj:GetValue( "FO1_IDDOC" ) ) == 0
                    aAdd(aIDDOC, oObj:GetValue( "FO1_IDDOC" ) )
                    For nI := 1 to oObj:Length()
                        oObj:GoLine(nI)
                        nValAux := 0
                        If cCli460 == 'CDESCO' .And. cTit == oObj:GetValue("FO1_NUM") // Cliente con descuento
                            nValAux     := oObj:GetValue("FO1_TOTAL") - nDescon
                            oObj:LoadValue("FO1_DESCON", nDescon)
                            oObj:LoadValue("FO1_TOTAL", nValAux)
                        EndIf
                        If cCli460 == 'JURMUL' .And. cTit == oObj:GetValue("FO1_NUM")// Cliente con interés y multa
                            nValAux     := oObj:GetValue("FO1_TOTAL")
                            nDias       := dDataBase - FDtVento()
                            oObj:LoadValue("FO1_TXJUR", nTxJur)
                            oObj:LoadValue("FO1_VLJUR", ( nValAux * nTxJur * nDias ) / 100 )
                            oObj:LoadValue("FO1_TXMUL", nTxMul)
                            oObj:LoadValue("FO1_VLMUL", ( nValAux * nTxMul ) / 100 )
                            oObj:LoadValue("FO1_VLADIC", 14.5)
                            nValAux     := nValAux + oObj:GetValue("FO1_VLADIC") + oObj:GetValue("FO1_VLMUL") + oObj:GetValue("FO1_VLJUR")
                            oObj:LoadValue("FO1_TOTAL", nValAux)
                        EndIf
                        nValTot += nValAux
                    Next
                EndIf
                
            EndIf
        ElseIf cIdPonto == 'MODELPOS'

            If cIdModel == "FINA460A"
                oObjFO2 := oObj:GetModel("TITGERFO2")
                nLenFO2 := oObjFO2:Length()
                nValParc := ( nValTot / nLenFO2 )
                For nI := 1 to nLenFO2
                    oObjFO2:GoLine(nI)
                    oObjFO2:LoadValue("FO2_TXJUR", 2 )
                    oObjFO2:LoadValue("FO2_VALOR", nValTot)
                    oObjFO2:LoadValue("FO2_TOTAL", nValTot)
                Next
            EndIf
        EndIf
    EndIf
EndIf

Return xRet

Static Function FDtVento()

    Local dData := CTOD("  /  /  ")
    Local aArea := SE1->(GetArea())

    dData   := Posicione( "SE1", 1, xFilial("SE1") + FK7->(FK7_PREFIXO + FK7_NUM + FK7_PARCELA + FK7_TIPO + FK7_CLIFOR + FK7_LOJA ), "E1_VENCREA" )

    RestArea(aArea)

Return dData