// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Reporte:     RESUMEN DE OPERACIONES DETALLADO                                
//
// Sistema:     ADMINPAQ  Versión v1.0 Windows
//
// Descripcion:Por Cada Cliente se Imprimira un resumen de sus operaciones realizadas de acuerdo
//             a un rango de fechas seleccionadas.
//             Este reporte representa la sección denominada como resumen y que es impresa al final 
//             de cada estado de cuenta
// Consideraciones :
// Creación  :  Felix de la Cruz S.   23/Julio/2001
// Revisiones : 
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha         Nombre    IDLotus     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//  08/04/2009    JENL      5171        NO APARECEN ALGUNOS CLIENTES QUE TIENEN SALDO AL EJECUTAR EL
//                                      REPORTE RESUMEN DE OPERACIONES INDICANDO EN EL FILTRO SOLO
//                                      LOS CLIENTES CON SALDO
//                                      Se modifico: principal
//  07/01/2009    ELVS      6140        Reportes - ERROR NO SE MUESTRAN TODOS LOS DOCUMENTOS AL 
//                                      INDICAR UN SOLO DIA EN EL FILTRO DEL REPORTE DE RESUMEN DE 
//                                      OPERACIONES DETALLADO DE CLIENTES Y SI  HAY INFORMACION 
//                                      EN ESE DIA. 
//**************************************************************************************************
// INCLUSION DE ARCHIVOS
//**************************************************************************************************
Incluye LibAdminPaq.rpt
Incluye LibCliProv.rpt

//**********************************************************************************************
// INICIO PARAMETROS
//**************************************************************************************************
Parametro pDeLaFecha    = '20010501'
Parametro pAlaFecha     = '20011231'
Parametro pDelCliente   = ' '       // clave del primer cliente en el rango
Parametro pAlCliente    = ' '       // clave del ultimo cliente en el rango
Parametro pListaCptos   = '5,11,13,14'        // Lista de los ID de los conceptos seleccionados
Parametro pSoloConDoctos  =  0      // 0 = Todos, 1 = Solo con documentos, 2 = Solo con saldos
Parametro pSoloConSaldo   =  0      // 0 = Todos, 1 = Solo con saldo
Parametro pCualesClientes =  0      // 0 = Todos, 1 = Activos, 2 = InActivos
Parametro pIdMoneda       =  1      // 1 = ID moneda Peso mexicano
Parametro pQueTipo        =  0      // 0 = Clientes, 1 = Proveedores
Parametro pIdClase1   = 0    // por omisión deben recibir 0 =  ninguna
Parametro pIdClase2   = 0    // deben ser el ID de la clasificacion
Parametro pIdClase3   = 0    
Parametro pIdClase4   = 0    
Parametro pIdClase5   = 0
Parametro pIdClase6   = 0    

//**********************************************************************************************
// INICIO APERTURA TABLAS
//**************************************************************************************************
// Nombres terminados en Lib, indican que la tabla fue abierta explicitamente para alguna Fx de libreria
UsaEmpresa tEmpresa;'AdminpaqW'               

// Periodos
UsaTabla tPeriodos = tEmpresa['mgw10031']              // Usa el indice primario, cIDEjercicio
tPeriodos.UsaIndice['cNumeroEjercicio']

// Parametros de la empresa
UsaTabla tParametros = tEmpresa['mgw10000']                          // Usa el indice primario
 
// TiposCambio 
Usatabla tTiposCambioLib = tEmpresa['mgw10035']
tTiposCambioLib.Usaindice['iMonedaFecha']                                  //  cIdMoneda + cFecha

// Documentos
UsaTabla tDocumentos = tEmpresa['mgw10008'] Alias 'tDoctos1'
tDocumentos.Usaindice['iClienteProvCptoFecha']//IdClienteProveedor+IdCpto+cFecha+cSerie+cFolio

UsaTabla tDoctoslib = tEmpresa['mgw10008']  Alias 'tDoctos2'               
tDoctosLib.UsaIndice['iClienteProveedorFecha']    //IdClienteProveedor+cFecha+cSerie+cFolio

// Clientes y Provedores
UsaTabla tClientes = tEmpresa['mgw10002']
tClientes.Usaindice['iCodigoTipo']                            // cCodigoCliente + cTipoCliente

// Acumulados por periodo
UsaTabla tAcumuladosLib = tEmpresa['mgw10018']     // cIdTipoAcumulado + cIdOwner1 + cIdOwner2 
tAcumuladosLib.Usaindice['iAcumImpteOwnerEjerMoneda']                 // + cIdEjercicio + cIdMoneda

UsaTabla tMonedas = tEmpresa['mgw10034']          
tMonedas.Usaindice['']                                 // Usa el índice primario, por cIdMoneda

UsaTabla tConceptos = tEmpresa['mgw10006']        // Tabla de conceptos, usa el indice primario
tConceptos.UsaIndice['']

UsaTabla tValoresDeClasif = tEmpresa['mgw10020']
tValoresDeClasif.UsaIndice['']

// Inicia N.D.1568
UsaTabla tDoctoModelo = tEmpresa['MGW10007']		 // Documentos modelos
tDoctoModelo.Usaindice['']
// Fin N.D.1568


//**************************************************************************************************
//DEFINICION DE COLUMNAS 
//**************************************************************************************************
          // C0  C1  C2   C3   C4   C5   C6   C7  
  Columnas 8;5.4,1.5,1.95,0.15,1.95,0.15,2.4,2.0  
  UsaLetra 'Arial'
  Altura 9
  [C0..C1].Decimales 0
  [C0..C1].Blanco ' '
  [C2..C6].Coma

  tMonedas.Busca[@Str(pIdMoneda;0)]
  gDecimales = tMonedas(cDecimalesMoneda)
  [C2..C6].Decimales gDecimales
  [C2..C6].Blanco '0.00'
  [C2..C6].Corchete True


//**************************************************************************************************
// VARIABLES GLOBALES 
//**************************************************************************************************
  gHoy = fFormateaFecha(@Hoy();0)
  gDelaFecha = ''
  gAlaFecha  = '' 
  gPeriodo   = 0
  gIdEjercicio = 0 
  gSaldoInicialCliente= 0.0         // Siempre tiene el saldo inicial del cliente

  // Se inicializan las variables de totales por concepto
  gTotalAbonosCpto = 0.0
  gTotalCargosCpto = 0.0

  gPosicion = 0                      // tiene el indice para el recorrido sobre la lista de Cptos.
  gNombreMoneda = tMonedas(cNombreMoneda)
  gNombresCptos = ''

  // Se inicializan las variables de totales por cliente
  gTotalCargosCliente = 0.0
  gTotalAbonosCliente = 0.0
  gTotalSaldoCliente  = 0.0

  gTotalCargosGral = 0.0
  gTotalAbonosGral = 0.0
  gTotalSaldosGral = 0.0

  Si pListaCptos = 0
    tConceptos.Busca Primero

    pListaCptos = ''
    Mientras tConceptos->Encontro
      tDoctoModelo.Busca[@Str(tConceptos(cIdDocumentoDe);0)]
      Si tDoctoModelo->Encontro Y ((pQueTipo = 0 Y tDoctoModelo(cUsaCliente)) O (pQueTipo = 1 Y tDoctoModelo(cUsaProveedor))) Y (tDoctoModelo(cNaturaleza) < 2 O tDoctoModelo(cIdDocum01) = 28 O tDoctoModelo(cIdDocum01) = 29 O tDoctoModelo(cIdDocum01) = 30 O tDoctoModelo(cIdDocum01) = 31)
        Si pQuetipo = 0 Y (tDoctoModelo(cIdDocum01) = 30 O tDoctoModelo(cIdDocum01) = 31)
          Continua
        FinSi
        Si pQuetipo = 1 Y (tDoctoModelo(cIdDocum01) = 28 O tDoctoModelo(cIdDocum01) = 29)
          Continua
        FinSi
        Si pListaCptos != ''
          pListaCptos = pListaCptos & ','
        FinSi
        pListaCptos = pListaCptos & tConceptos(cIdConceptoDocumento)
      FinSi
      tConceptos.SaltaReg[1]
    FinMientras
  FinSi

//**************************************************************************************************
// F U N C I O N E S
//**************************************************************************************************
// =================================================================================================
// Función área sensible al contexto
// =================================================================================================
DefFunc ContextoDetalleClienteCpto(aNumeroColumna; aValor)
    EJECUTA tEmpresa->SysDirDatos & '\Reportes\AdminPAQ\AuxMovPorCpto.RTW';pDeLaFecha,pAlaFecha,@Escoge(aValor;0),@Escoge(aValor;0),@Escoge(aValor;1),0,pCualesClientes,pIdMoneda,pQueTipo,pIdClase1,pIdClase2,pIdClase3,pIdClase4,pIdClase5,pIdClase6;tEmpresa->Directorio
FinFunc

//**************************************************************************************************
// Descripcion : Establece uno de los dos tipos de columnas que se utilizan en el reporte
// Entrada :     atipo : El tipo de de columnas
//**************************************************************************************************
Deffunc fColumnas(atipo)
  Si atipo = 1
            // C0  C1  C2   C3   C4   C5   C6  C7  
    Columnas 8;5.4,1.5,1.95,0.15,1.95,0.15,2.4,2.0 // la ultima col. solo es ornamental
  Sino 
    Si pQueTipo = 0
               // C0  C1   C2 
      Columnas 5;1.2,0.15,6.45
    Sino
               // C0  C1   C2 
      Columnas 5;1.5,0.15,6.45      
    Finsi 
  Finsi
Finfunc

//**************************************************************************************************
//    Esta función recupera y guarda en una lista, los nombres de los conceptos, para tenerlos 
//    en memoria y evitar lectura con cada cliente.
//**************************************************************************************************
Deffunc fCargaNombresCptos()
Local lPosicion

  lPosicion = 0
  Mientras @Escoge(pListaCptos;lPosicion) != ''          
    tConceptos.Busca[@Escoge(pListaCptos;lPosicion)]    
    Si lPosicion = 0
      gNombresCptos = tConceptos(cNombreConcepto)
    Sino
      gNombresCptos = gNombresCptos & ','&tConceptos(cNombreConcepto)
    Finsi
    lPosicion = lPosicion +1
  FinMientras
FinFunc

//**************************************************************************************************
// Descripcion : Imprime los datos del cliente, como encabezado para despues imprimir el detalle
//               Obtiene el saldo inicial ya que es parte de los datos del cliente
// Entrada : La tabla de clientes, con el cliente a imprimir abierto
// Salida  : No regresa valor,
//           pero imprime los renglones de 1.- Datos del cliente;  1.- Saldo inicial el cliente
//**************************************************************************************************
DefFunc fImpDatosCliente(aTblCliente:TABLA;aSaldo;aTipo)
local lRenglon   

  NEGRITAS TRUE       
  fColumnas(2) 
  lRenglon = ''
  Si aTipo = 0
    lRenglon[0] = 'Cliente:'
  Sino
    lRenglon[0] = 'Proveedor:'
  Finsi
  lRenglon[2] = fMascarilla(aTblCliente(cCodigoCliente);tParametros(cMascarillaClientes))
  Imprime lRenglon
  lRenglon[0] = 'Nombre:'
  lrenglon = aTblCliente(cRazonSocial)[C2]
  Imprime lrenglon
  Imprime 1
  NEGRITAS FALSE
  fColumnas(1)
  lRenglon = ''
  lRenglon[0] = 'Saldo Inicial'
  lRenglon[6] = aSaldo
  Imprime lRenglon
FinFunc

//**************************************************************************************************
// Descripcion : Imprime los totales por Concepto
// Entradas :
//           aPos =  Posición en la lista de ID de conceptos; para buscar el nombre
//           aSaldo =  Saldo despues de cargos y abonos ocasionados por el concepto
//           aCargos = Total de cargos
//           aAbonos = Total de abonos
//**************************************************************************************************
Deffunc fImprimeDetalle(aPos;aSaldoIni; aCargos;aAbonos)
Local lRenglon, lDatos

  lRenglon = ''[C0..C6]
  lRenglon[0] = @Escoge(gNombresCptos;aPos)
  lRenglon[2] = aCargos
  lRenglon[4] = aAbonos    
  lRenglon[6] = aSaldoIni
  DEFREGION ContextoDetalleClienteCpto
  lDatos = tClientes(cCodigoCliente) & ',' & @Escoge(pListaCptos; gPosicion)
  Si aCargos != 0
    [C2].REGIONINFO lDatos
  FinSi
  Si aAbonos != 0
    [C4].REGIONINFO lDatos
  FinSi
  Imprime lRenglon
  // Acumula los totales del cliente
  gTotalAbonosCliente = gTotalAbonosCliente + aAbonos
  gTotalCargosCliente = gTotalCargosCliente + aCargos
FinFunc

//**************************************************************************************************
// Descripcion : Imprime los totales para elCliente
// Entradas    : Toma los valores globales para el cliente
//**************************************************************************************************
Deffunc fImprimeTotalesCliente(aSaldo)
Local lRenglon

  [C2,C4,C6].Subrayacol '-'  
  lRenglon[2] = gTotalCargosCliente
  lRenglon[4] = gTotalAbonosCliente
  lRenglon[6] = aSaldo  
  Imprime lRenglon
  Imprime 1
  // Acumula los totales generales
  gTotalCargosGral = gTotalCargosGral + gTotalCargosCliente
  gTotalAbonosGral = gTotalAbonosGral + gTotalAbonosCliente
  gTotalSaldosGral = gTotalSaldosGral + aSaldo
  // Se inicializan las variables de totales por cliente
  gTotalCargosCliente = 0.0
  gTotalAbonosCliente = 0.0
FinFunc

//**************************************************************************************************
// Descripcion : Imprime los totales generales de la corrida del reporte
// Entradas    : Toma los valores globales 
//**************************************************************************************************
Deffunc fImprimeGranTotal()
Local lRenglon, lSubRaya

  lSubRaya = ''
  lSubRaya = '==================='[C2,C4,C6]
  
  lRenglon[2] = gTotalCargosGral
  lRenglon[4] = gTotalAbonosGral
  lRenglon[6] = gTotalSaldosGral

  Saltalin 1
  Imprime lSubRaya
  Imprime lRenglon
FinFunc

//**************************************************************************************************
// Salidas:  1 = indica que el cliente no aplica, debe descartarse
//           0 = indica que el cliente no debe descartarse.
//**************************************************************************************************
DefFunc fDiscriminaCliente(aCliente:TABLA)
Local lRegresa
    
  lRegresa = 0

  // Se salta el Cliente NINGUNO
  Si aCliente(cIdClienteProveedor) = 0
    lRegresa = 1
  Finsi
  // Si se requieren los clientes y no se trata de un cliente:(1=cliente,2=cliente/provedor,3= proveedor)
  Si  pQueTipo = 0 Y (aCliente(cTipoCliente) > 2) 
    lRegresa = 1
  Finsi
  // Si se requieren los Proveedores y no se trata de un Proveedor
  Si  pQueTipo = 1 Y (aCliente(cTipoCliente) < 2) 
    lRegresa = 1
  Finsi
  // Si Estado solicitado no es Todos y No Coincide el tipo de cliente con el parametro 
  // pCualesClientes = 2(inactivos) aplicando %2 = 0, 0 = inactivos en la tabla de clientes
  Si (pCualesClientes != 0) Y (aCliente(cEstatus) != pCualesClientes%2)
    lRegresa = 1
  Finsi
  // Se Revisan las CLASIFICACIONES, solo en el caso de haber seleccionado al menos una 
  Si gNumDeClases > 0
    Si !fMiembroDeUnaClase(aCliente;gNumDeClases;gListIdDeClases;pQueTipo)
     // Sa salta el cliente actual, por no pertenecer a alguna de las clasificaciones
      lRegresa = 1
    Finsi
  Finsi
  Retorna lRegresa
FinFunc

//**************************************************************************************************
//**************************************************************************************************
Deffunc fNaturaleza(atDocto:TABLA)
Local lNaturaleza
    
  // Se verifica la naturaleza por aquellos doctos de Utilidad O perdida Cambiaria
  lNaturaleza = atDocto(cNaturaleza)
    // 28. Utilidad Cambiaria Cliente (cargo)
    // 29. Perdida Cambiaria  Cliente (abono)
    // 30. Utilidad Cambiaria Provedor(abono)
    // 31. Perdida Cambiaria Proveedor(cargo)
  Si atDocto(cIdDocumentoDe) = 28 O atDocto(cIdDocumentoDe)= 30
    lNaturaleza = 0 // son cargos
  Finsi
  Si atDocto(cIdDocumentoDe) = 29 O atDocto(cIdDocumentoDe)= 31
    lNaturaleza = 1 // son abonos
  Finsi
  Retorna lNaturaleza
FinFunc

//**************************************************************************************************
// Salidas:  1 = indica que el Docto no aplica, debe descartarse
//           0 = indica que el Docto no debe descartarse.
//**************************************************************************************************
DefFunc fDiscriminaDocto(atDocumento:TABLA)
Local lRegresa

  lRegresa = 0

  // Si no es cargo o abono y no es docto de utilidad o perdida cambiaria)
  Si atDocumento(cNaturaleza) = 2 Y !(atDocumento(cIDDocumentoDe) >= 28 Y atDocumento(cIDDocumentoDe) <= 31) 
    lRegresa =1
  Finsi
  // Si no esta afectado se lo brinca
  Si atDocumento(cAfectado) != 1
    lRegresa =1
  Finsi

  // Los documentos de utilidad perdida cambiaria solo se incluyen si su moneda corresponde a la del reporte
  Si atDocumento(cIdDocumentoDe) >= 28 Y atDocumento(cIdDocumentoDe) <= 31 
    Si atDocumento(cIdMoneda) != pIdMoneda
      lRegresa = 1
    FinSi
  FinSi

  // CASO Clientes/Proveedores : se descartan los cargos que no son de clientes y los abonos
  // que no son de proveedores, solo imprime los doctos de acuerdo a el tipo de reporte pedido
  Si pQueTipo = 0 y atDocumento(cUsaCliente) = 0 // cargo pero no es docto de cliente
    lRegresa =1
  Finsi
  Si pQueTipo = 1 y atDocumento(cUsaProveedor) = 0 // abono pero no es docto de proveedor
    lRegresa =1
  Finsi
  Retorna lRegresa
FinFunc


//**************************************************************************************************
//ENCABEZADO 
//**************************************************************************************************
Encab   
  Texto '@TC{0,0,0}@S{8}AdminPAQ' 
  Hoja '"@TC{0,0,0}@S{8}Hoja: ' 
  Imprime 
  Texto '@TC{0,0,0}@S{8}Moneda: ' & gNombreMoneda
  Texto '"@TC{0,0,0}@S{8}Fecha: ' & gHoy
  Imprime
  Texto '^@TC{0,0,0}@S{22}' & tEmpresa->Nombre
  Imprime
  Texto '^@TC{0,0,0}@S{16}' & 'RESUMEN DE OPERACIONES DETALLADO'
  Imprime

  gDelaFecha = fFormateaFecha(pDelaFecha;0)
  gAlaFecha  = fFormateaFecha(pAlaFecha;0)
  Texto '^@TC{0,0,0}@S{16}'& 'Del: ' & gDelaFecha & ' Al: ' & gAlaFecha 
  Imprime 

  // ===== Se Revisan las clasificaciones, para recuperarlas e imprimirlas en el encabezado
  fRevisaClases(tValoresDeClasif)
  // ===== Fin de la revision de clasificaciones

  NEGRITAS TRUE
  Altura 9
  Texto '@TC{0,0,0}@L{-1}'
  Imprime 
  Texto C0;'Concepto'
  Texto C2;'^Cargos'
  Texto C4;'^Abonos'
  Si pQueTipo = 0
    Texto C6;'Saldo Cliente'  
  Sino
    Texto C6;'Saldo Proveedor'
  Finsi
  Imprime 1
  Texto '@TC{0,0,0}@L{-1}'
  Imprime 
  NEGRITAS FALSE    
FinEncab

//**************************************************************************************************
// P R I N C I P A L
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha         Nombre    IDLotus     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//  08/04/2009    JENL      5171        Se manda el periodo de la fecha una vez incrementada, puesto
//                                      que si la fecha incrementada corresponde a otro periodo, la
//                                      funcion fSaldoInicial no calcula el saldo correctamente.
//**************************************************************************************************
Si pDelCliente = ' '
  tClientes.Busca Primero
  pDelCliente = tClientes(cCodigoCliente)
Finsi
  
Si pAlCliente = ' '
  tClientes.Busca Ultimo
  pAlCliente =  tClientes(cCodigoCliente)  
Finsi

// primeto carga todos los nombres de los conceptos, solo una vez
fCargaNombresCptos()

tParametros.Busca Primero   

fEjercicioPeriodo(pDelaFecha;&gPeriodo;&gIdEjercicio;tPeriodos)  

// Esta función se debe ejecutar antes del cuerpo del reporte, para inicializar algunas valores
// Globales para la biblioteca LibAdminPAQ.rpt
fIniFechasHistoria(tPeriodos)

Mientras [tClientes.Busca[pDelCliente & '..'  & pAlCliente ]; tClientes->Encontro ; tClientes.Busca Siguiente[1]]
  gSaldoInicialCliente= 0.0         // Siempre tiene el saldo inicial del cliente  
  Si fDiscriminaCliente(tClientes) =1
    Continua
  Finsi

  // Solo incluir clientes con moneda base o con moneda del reporte
  Si pIdMoneda != 1 Y pIdMoneda != tClientes(cIdMoneda)
    Continua
  FinSi

  // Se inicializa la fecha con la que se realizaran las busquedas en el rango de fechas
  gFechaBusqueda = pDeLaFecha  
  gPosicion = 0

  // Obtención del saldo del cliente a la fecha de fin del reporte
  // El saldo se toma a la fecha de fin del reporte más un dia, ya que de otra forma no se consideran los documentos del dia final del reporte
  lFechaSaldo = fFechaSiguiente(pAlaFecha)
  fEjercicioPeriodo(lFechaSaldo;&gPeriodo1;&gIDEjercicio1;tPeriodos)
  // Restaurar el periodo y ejercicio inicial del reporte
  fEjercicioPeriodo(pDelaFecha;&gPeriodo;&gIdEjercicio;tPeriodos)    
  gSaldoInicialCliente = fSaldoInicial(tClientes;gIdEjercicio;gPeriodo;pIdMoneda;pDelaFecha;pQueTipo;tAcumuladosLib;tDocumentos;tTiposCambioLib)  
  Si pSoloConSaldo = 1 
    gSaldoFinalCliente = fSaldoInicial(tClientes;gIdEjercicio1;gPeriodo1;pIdMoneda;lFechaSaldo;pQueTipo;tAcumuladosLib;tDocumentos;tTiposCambioLib)//N.D.5171
    Si (gSaldoFinalCliente = 0.0 Y gSaldoInicialCliente = 0.0)
      Continua
    FinSi
  FinSi

  // busca Algun docto , debe estar afectado y dentro del rango, OJO: el campo afecta no existe
  // Si encontro tDocumentos queda en el registro encontrado y gFechaBusqueda en la fecha en que se encontro
  //RCVG 5241
  gPosicion = 0
  Mientras @Escoge(pListaCptos;gPosicion)
    // Localización del primer documento para el cliente/proveedor
    // NOTA: Es obligatorio volver a fijar el índice a fin de que las búsquedas parciales funcionen correctamente
    tDocumentos.Usaindice['iClienteProvCptoFecha']
    tDocumentos.Busca[tClientes(cIdClienteProveedor) &':'& @Escoge(pListaCptos;gPosicion) & ':' & pDeLaFecha]
    //N.D.6140 Cuando la fecha de inicio y fin son iguales y encontraba el documento en la primera vuelta
    //no se salía del ciclo, lo cual dejaba mal posicionado la posición del registro del documento y nunca mostraba
    //registros
    Si tDocumentos->ENCONTRO
    	FinCiclo
    FinSi
    
    Si !tDocumentos->ENCONTRO
      // Busquedas parciales: Cursor en el registro más cercano que cumple con la llave
      // NOTA: La propiedad Llave de la tabla nos regresa la llave más cercana que cumple con el criterio de la búsqueda
      //       La llave está en formato cadena y no tiene ningún separador entre los campos, por lo que es necesario revisar
      //      en FoxPro la definición del índice para descomponer los elementos de la Llave
      Si tClientes(cIdClienteProveedor) = @Val(@SUBSTR(tDocumentos->Llave;0;11))
        Si @Val(@Escoge(pListaCptos; gPosicion)) = @Val(@SUBSTR(tDocumentos->Llave;11;11))
          Si @SUBSTR(tDocumentos->Llave;22;8) >= pDeLaFecha Y @SUBSTR(tDocumentos->Llave;22;8) <= pAlaFecha
            // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro
            gFechaBusqueda = @SUBSTR(tDocumentos->Llave;22;8)
            tDocumentos.Busca[tClientes(cIdClienteProveedor) &':'& @Escoge(pListaCptos;gPosicion) & ':' & gFechaBusqueda]
            FinCiclo
          FinSi
        FinSi
      FinSi        
    FinSi
    gPosicion = gPosicion + 1 
  FinMientras 
  // gPosicion tiene la posicion del Primer ID que encontro si no encontró

  // Todos aun sin Doctos, el Cliente si tiene Doctos
  Si (pSoloConDoctos = 0) O (tDocumentos->ENCONTRO)
    //gSaldoInicialCliente = fSaldoInicial(tClientes;gIdEjercicio;gPeriodo;pIdMoneda;pDelaFecha;pQueTipo;tAcumuladosLib;tDoctoslib;tTiposCambioLib)

    fImpDatosCliente(tClientes;gSaldoInicialCliente;pQueTipo)
    
    gPosicion = 0 //RCVG 5241 
    Mientras @Escoge(pListaCptos; gPosicion)
      // Localización del primer documento para el cliente/proveedor
      // Búsqueda de un documento del cliente/proveedor a la fecha inicial del reporte
      // Se inicializa la fecha con la que se realizaran las busquedas en el rango de fechas
      gFechaBusqueda = pDeLaFecha  
      // NOTA: Es obligatorio volver a fijar el índice a fin de que las búsquedas parciales funcionen correctamente
      tDocumentos.Usaindice['iClienteProvCptoFecha']
      tDocumentos.Busca[tClientes(cIdClienteProveedor) & ':' & @Escoge(pListaCptos; gPosicion) & ':' & gFechaBusqueda]
      Si !tDocumentos->ENCONTRO
        // Busquedas parciales: Cursor en el registro más cercano que cumple con la llave
        // NOTA: La propiedad Llave de la tabla nos regresa la llave más cercana que cumple con el criterio de la búsqueda
        //       La llave está en formato cadena y no tiene ningún separador entre los campos, por lo que es necesario revisar
        //      en FoxPro la definición del índice para descomponer los elementos de la Llave
        // Revisar si la llave actual corresponde al Producto / Almacén y al Rango de Fechas.
        Si tClientes(cIdClienteProveedor) = @Val(@SUBSTR(tDocumentos->Llave;0;11))
          Si @Escoge(pListaCptos; gPosicion) = @Val(@SUBSTR(tDocumentos->Llave;11;11))
            Si @SUBSTR(tDocumentos->Llave;22;8) >= pDeLaFecha Y @SUBSTR(tDocumentos->Llave;22;8) <= pAlaFecha
              // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro
              gFechaBusqueda = @SUBSTR(tDocumentos->Llave;22;8)
              tDocumentos.Busca[tClientes(cIdClienteProveedor) & ':' & @Escoge(pListaCptos; gPosicion) & ':' & gFechaBusqueda]
            FinSi
          FinSi
        FinSi        
      FinSi

      // Procesamiento de los documentos con fecha anterior a la fecha de fin del reporte
			Mientras tDocumentos->Encontro y tDocumentos(cFecha) <= pAlaFecha
        Si fDiscriminaDocto(tDocumentos) = 1
          tDocumentos.Busca siguiente[2]
          Continua
        Finsi
        // Expresar el importe en la moneda del reporte
        gImporteMonedaRPT = fCambiarMonedaDoctoAReporte(tDocumentos; tTiposCambioLib; tDocumentos(cTotal); pIdMoneda; tClientes(cIdMoneda))
        Si fNaturaleza(tDocumentos) = 0  // Se trata de un cargo
          gImporteMonedaRPT = pQueTipo = 0? gImporteMonedaRPT : -gImporteMonedaRPT
          gTotalCargosCpto = gTotalCargosCpto + gImporteMonedaRPT
        Sino
          gImporteMonedaRPT = pQueTipo = 1? gImporteMonedaRPT : -gImporteMonedaRPT
          gTotalAbonosCpto = gTotalAbonosCpto + gImporteMonedaRPT
        Finsi
        tDocumentos.Busca siguiente[2]
      FinMientras 

      gSaldoInicialCliente = gSaldoInicialCliente + gTotalAbonosCpto + gTotalCargosCpto

      // Impresión del detalle con los totales de concepto
      Si (@Abs(gTotalCargosCpto) > 0.0 O @Abs(gTotalAbonosCpto) > 0.0)
        fImprimeDetalle(gPosicion;gSaldoInicialCliente;gTotalCargosCpto;gTotalAbonosCpto)
        // Se inicializan las variables de totales por concepto
        gTotalAbonosCpto = 0.0
        gTotalCargosCpto = 0.0    
      Finsi

      // reinicia la fecha para seguir con la busqueda desde la fecha inicial
      gFechaBusqueda = pDeLaFecha  
      gPosicion = gPosicion + 1
    FinMientras
      
    // se imprimen los totales del cliente
    fImprimeTotalesCliente(gSaldoInicialCliente)
  Finsi 
FinMientras
   
// se imprimen los totales generales
fImprimeGranTotal()

// FIN DEL REPORTE

