// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Reporte:     RESUMEN DE OPERACIONES                                   
//
// 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.   10/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
//**************************************************************************************************

//**************************************************************************************************
// 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 pSoloConDoctos  =  0      // 0 = Todos, 1 = Solo con documentos
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'               

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

UsaTabla tParametros = tEmpresa['mgw10000']                        // Usa el indice primario

Usatabla tTiposCambioLib = tEmpresa['mgw10035']
tTiposCambioLib.Usaindice['iMonedaFecha']                                  //  cIdMoneda + cFecha

UsaTabla tDocumentos = tEmpresa['mgw10008'] 
tDocumentos.Usaindice['iClienteProveedorFecha']   //IdClienteProveedor+cFecha+cSerie+cFolio

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

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 tValoresDeClasif = tEmpresa['mgw10020']
tValoresDeClasif.UsaIndice['']


//**********************************************************************************************
//DEFINICION DE COLUMNAS 
//**************************************************************************************************
              // C0     C2        C4        C6        C8        C10
  Columnas 11; 2.1,0.15,5.4,0.15,1.95,0.15,1.95,0.15,1.95,0.15,2.25
  UsaLetra 'Arial'
  Altura 9
  [C0..C2].Decimales 0
  [C0..C2].Blanco ' '
  [C3..C10].Coma
  [C3..C10].Corchete True

  tMonedas.Busca[@Str(pIdMoneda;0)]
  gDecimales = tMonedas(cDecimalesMoneda)
  [C3..C10].Decimales gDecimales
  [C3..C10].Blanco '0.00'


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

  gTotalGralInicial = 0.0
  gTotalGralCargos = 0.0
  gTotalGralAbonos = 0.0
  gTotalGralFinal = 0.0

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

//**************************************************************************************************
// Descripcion : Imprime los totales por Cliente/Proveedor
// Comentarios : asume la misma distribucion de columnas que el cuerpo principal del reporte
//**************************************************************************************************
Deffunc fImprimeResumen(aTblCliente:Tabla;aSaldoIni;aCargos;aAbonos;aTipo)
Local lRenglon, lSaldoFinal

  lRenglon = ''
  lRenglon[0] = fMascarilla(aTblCliente(cCodigoCliente);tParametros(cMascarillaClientes))
  lRenglon = aTblCliente(cRazonSocial)[C2]  
  lRenglon[4] = aSaldoIni
  lRenglon[6] = aCargos
  lRenglon[8] = aAbonos
  lSaldoFinal = (aSaldoIni + aCargos + aAbonos)
  lRenglon[10]= lSaldoFinal

  DEFREGION ContextoDetalleCliente
  Si aCargos != 0
    [C6].REGIONINFO aTblCliente(cCodigoCliente)
  FinSi
  Si aAbonos != 0
    [C8].REGIONINFO aTblCliente(cCodigoCliente)
  FinSi
  Imprime lRenglon

  gTotalGralInicial = gTotalGralInicial + aSaldoIni
  gTotalGralCargos  = gTotalGralCargos + aCargos
  gTotalGralAbonos  = gTotalGralAbonos  + aAbonos
  gTotalGralFinal   = gTotalGralFinal + lSaldoFinal
FinFunc

//**************************************************************************************************
// Esta función solo imprime los totales generales al final del reporte
//**************************************************************************************************
Deffunc fImprimeTotales()
Local lRenglon, lSubRaya

  lSubRaya = ''
  lSubRaya = '================='[C4,C6,C8,C10]
  lRenglon[4] = gTotalGralInicial 
  lRenglon[6] = gTotalGralCargos
  lRenglon[8] = gTotalGralAbonos
  lRenglon[10] = gTotalGralFinal
  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'
  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 
  Si pQueTipo = 0
    Texto C2;'Nombre (Cliente)'
    Texto C10;'Saldo Cliente'
  Sino
    Texto C2;'Nombre (Proveedor)'
    Texto C10;'Saldo Proveedor'
  Finsi
  Texto C0;'Código'
  Texto C4;'Saldo Inicial'
  Texto C6;'^Cargos'
  Texto C8;'^Abonos'
  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

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]] 
  // Validación 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 inicializan las variables de totales por cliente
  gTotalAbonosCliente = 0.0
  gTotalCargosCliente = 0.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)    
  Si pSoloConSaldo = 1
    gSaldoFinalCliente = fSaldoInicial(tClientes;gIdEjercicio1;gPeriodo1;pIdMoneda;lFechaSaldo;pQueTipo;tAcumuladosLib;tDocumentos;tTiposCambioLib)//N.D.5171
    gSaldoInicialCliente = fSaldoInicial(tClientes;gIdEjercicio;gPeriodo;pIdMoneda;pDelaFecha;pQueTipo;tAcumuladosLib;tDocumentos;tTiposCambioLib)
    Si (gSaldoFinalCliente = 0.0 Y gSaldoInicialCliente = 0.0)
      Continua
    FinSi
  FinSi
                     
  // 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['iClienteProveedorFecha']
  tDocumentos.Busca[tClientes(cIdClienteProveedor) & ':' & 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 @SUBSTR(tDocumentos->Llave;11;8) >= pDeLaFecha Y @SUBSTR(tDocumentos->Llave;11;8) <= pAlaFecha
        // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro
        gFechaBusqueda = @SUBSTR(tDocumentos->Llave;11;8)
        tDocumentos.Busca[tClientes(cIdClienteProveedor) & ':' & gFechaBusqueda]
      FinSi
    FinSi        
  FinSi

  // Procesamiento de los documentos con fecha anterior a la fecha de fin del reporte
	Mientras tDocumentos->Encontro y tDocumentos(cFecha) <= pAlaFecha
    // Se saltan los doctos que no deben aplicar
    Si fDiscriminaDocto(tDocumentos) = 1
      tDocumentos.Busca siguiente[1]
      Continua
    Finsi	
    // Expresar el importe en la moneda del reporte
    gImporteMonedaRPT = fCambiarMonedaDoctoAReporte(tDocumentos; tTiposCambioLib; tDocumentos(cTotal); pIdMoneda; tClientes(cIdMoneda))
    Si fNaturaleza(tDocumentos) = 0  // es un cargo
      // para los proveedores los cargos se ponen en negativo
      gImporteMonedaRPT = (pQueTipo = 0? gImporteMonedaRPT : -gImporteMonedaRPT)
      gTotalCargosCliente = gTotalCargosCliente + gImporteMonedaRPT
    Sino
      // Para los proveedores los abonos se ponen enn negativo
      gImporteMonedaRPT = (pQueTipo = 1? gImporteMonedaRPT : -gImporteMonedaRPT)            
      gTotalAbonosCliente = gTotalAbonosCliente + gImporteMonedaRPT
    Finsi         
    tDocumentos.Busca siguiente[1]
  FinMientras

  Si (pSoloConDoctos = 0) O (gTotalCargosCliente != 0.0) O (gTotalAbonosCliente != 0.0)
    gSaldoInicialCliente = fSaldoInicial(tClientes;gIdEjercicio;gPeriodo;pIdMoneda;pDelaFecha;pQueTipo;tAcumuladosLib;tDocumentos;tTiposCambioLib)
    fImprimeResumen(tClientes; gSaldoInicialCliente;gTotalCargosCliente;gTotalAbonosCliente;pQueTipo)
  Finsi

FinMientras 
  
fImprimeTotales()

// FIN DEL REPORTE

