// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Reporte:     DOCUMENTOS RELACIONADOS
//
// Sistema:     ADMINPAQ  Versión v10.0 Windows
//
// Descripcion:  Reporte que imprime la relación de abonos timbrados vs xml generado y factura pagada
//		 Unicamente se imprimirán pagos electrónicos, y el reporte de despliega 
//		 ordenado por fecha-serie-folio pago
// Consideraciones :  La información se obtiene de datos almacenados en tablas, no lee los xml
// Creación  :  Agosto 2017
// Revisiones : 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//******************************************************************************
//Funciones de librería.

  Incluye LibAdminPaq.rpt
  Incluye LibDigitales.rpt
//******************************************************************************
//Parámetros.
    
  Parametro pDeLaFecha      = '20170101'
  Parametro pAlaFecha       = '20171231'
  Parametro pDeLaCuenta     = ' '      // Código de la Cuenta bancaria EMPRESA
  Parametro pALaCuenta      = ' '      // Código de la Cuenta bancaria EMPRESA
  Parametro pIdMoneda       = 1        // 1 = ID moneda Peso mexicano 
  

//******************************************************************************
//Apertura de tablas.

//Nombres terminados en Lib, indican que la tabla fue abierta explícitamente 
//para alguna Fx de librería

  UsaEmpresa tEmpresa;'AdminpaqW'               

  //Periodos. 
  //Índice: cNumeroEjercicio
  UsaTabla tPeriodos = tEmpresa['mgw10031']
  tPeriodos.UsaIndice['cNumeroEjercicio']

  //Parametros de la empresa. 
  //Índice: primario.
  UsaTabla tParametros = tEmpresa['mgw10000']                        

  Usatabla tCuentas = tEmpresa['mgw10056'] Alias 'tCuenta'
  tCuentas.Usaindice['']

  Usatabla tCuentasFiltro = tEmpresa['mgw10056'] Alias 'tCuenta1'
  tCuentasFiltro.Usaindice['INUMEROC01']
                           
  //Documentos. 
  UsaTabla tPagos = tEmpresa['mgw10008'] Alias 'tDoctos1'  
  tPagos.Usaindice['cFecha']   //

  UsaTabla tDocumentos = tEmpresa['mgw10008'] Alias 'tDoctos2'  
  tDocumentos.Usaindice['']   //

  UsaTabla tDoctoLib = tEmpresa['mgw10008'] Alias 'tDoctos3'  
  tDoctoLib.Usaindice['']   //

  UsaTabla tDigitales = tEmpresa['mgw10045'] Alias 'tDigital1'
  tDigitales.Usaindice['CIDDOCTO']


  UsaTabla tDigitalDocto = tEmpresa['mgw10045'] Alias 'tDigital2'
  tDigitalDocto.Usaindice['CIDDOCTO']

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

  //Cargos y Abonos. 
  //Índice: IDDoctoAbono + IDDoctoCargo
  UsaTabla tCargosAbonos = tEmpresa['mgw10009']   Alias 'tCA1'
  tCargosAbonos.UsaIndice['']

  //Índice: IDDoctoCargp + IDDoctoAbono
  UsaTabla tCargosAbonosLib = tEmpresa['mgw10009']   Alias 'tCA2'
  tCargosAbonosLib.UsaIndice['IDOCTOCA01']
  
  //Monedas. 
  //Índice: primario.
  UsaTabla tMonedas = tEmpresa['mgw10034']          
  tMonedas.Usaindice['']                        

  pIdMoneda = 1
  tMonedas.Busca[@Str(pIdMoneda;0)] 
  gDecimales = tMonedas(cDecimalesMoneda)


//******************************************************************************
//Declaración de variables globales.

  Columnas 1;5
  
  
  gHoy = fFormateaFecha(@Hoy();0)
  gNombreMoneda = tMonedas(cNombreMoneda)

// *************************************
// Definicion de constantes de EXCEL
// *************************************
constante xlCentrarEnSeleccion  7
constante xlAutomatico          -4105
constante xlManual              -4135
constante xlInferior            -4107
constante xlSubrayadoDoble      -4119
constante xlIzquierda           -4131
constante xlMediano             -4138
constante xlNinguno             -4142
constante xlDerecha             -4152
constante xlSuperior            -4160
constante xlHojaCalculo         -4167
constante xlLineaSimple		1
constante xlBordeSuperior	8
constante xlBordeInferior	9
constante xlBordeIzquierda	7
constante xlBordeDerecha	10
constante xlCentro		-4108
constante xlSaltoPagina -4135

// *************************************
// Inicializa EXCEL
// *************************************
// Accesa objetos de excel. Crea un objeto de Excel con la funcion @CreaObjeto(). A esta funcion
// se le pasa un identificador de OLE de la aplicacion que se desea crear. En este caso el identificador
// es Excel.Application.5
Objeto Excel = @CreaObjeto('Excel.Application')

// Invoca el metodo de EXCEL Libros y luego el metodo Agregar para crear un libro de hoja de calculo
// representado por la constante de EXCEL (xlHojaCalculo).
// Es importante notar que estos metodos NO LOS EJECUTA EL REPORTEADOR sino que los hace EXCEL
// y estan documentados en el Help de EXCEL
Objeto wb = Excel.WorkBooks.Add(xlHojaCalculo)

// Accesa la hoja de calculo (HojasCalculo) numero 1 del Libro creado anteriormente
// y representado por la variable wb, de la instruccion anterior
Objeto ws = wb.Worksheets(1)

// Hace visible a EXCEL. Para Excel, TRUE o VERDADERO es -1, FALSE o FALSO es 0
Excel.ActiveWindow.DisplayGridlines = FALSE[C0]
Excel.Visible = -1[C0]

RenActual = 1

// Pone la longitud de cada columna
ws.Columns(1).ColumnWidth = 38[C0] // A
ws.Columns(2).ColumnWidth = 10[C0] // B
ws.Columns(3).ColumnWidth = 12[C0] // C
ws.Columns(4).ColumnWidth = 20[C0]  //D
ws.Columns(5).ColumnWidth = 8[C0]   //E
ws.Columns(6).ColumnWidth = 14[C0]  //F
ws.Columns(7).ColumnWidth = 33[C0]  //G
ws.Columns(8).ColumnWidth = 13[C0]  //H
ws.Columns(9).ColumnWidth = 16[C0]  //I
ws.Columns(10).ColumnWidth = 20[C0]  //J
ws.Columns(11).ColumnWidth = 14[C0]  //K
ws.Columns(12).ColumnWidth = 14[C0]  //L
ws.Columns(13).ColumnWidth = 38[C0]  //M
ws.Columns(14).ColumnWidth = 11[C0]  //N
ws.Columns(15).ColumnWidth = 12[C0]  //O

lDigsDecimales = '0000000000'
lDecs = @SUBSTR(lDigsDecimales;1;gDecimales)

lFormato = '#,##0.' & lDecs & '_);(#,##0.' & lDecs & ')'
ws.Columns(9).NumberFormat = lFormato[C0]
lFormato = '#,##0.0000_);(#,##0.0000)'
ws.Columns(6).NumberFormat = lFormato[C0]

//******************************************************************************
//Funciones.

// ==========================================================================================
// fImprimeEstado
// Descripcion :   Regresa el número de pago que representa el abono que se envia con 
//                 respecto a la factura que esta pagando
// Salida:  Número de pago
// ==========================================================================================
DefFunc fNumeroParcialidad(aTblPago:TABLA; aTblDocumento:TABLA; aTblCargosAbonosLib:TABLA;aTblDoctoLib:TABLA)
    Local lRegresa, lContinua, lImporte
    lRegresa = 0
    lContinua = true
    lImporte = 0
    Mientras[aTblCargosAbonosLib.Busca[@STR(aTblDocumento(cIdDocumento);0)]; (lContinua Y aTblCargosAbonosLib->Encontro); aTblCargosAbonosLib.Busca Siguiente[1]]    
        aTblDoctoLib.Busca[@STR(aTblCargosAbonosLib(cIdDocum01);0)]
        Si ATblDoctoLib->ENCONTRO 
            lRegresa = lRegresa + 1
            Si aTblPago(cIdDocumento) = aTblCargosAbonosLib(cIdDocum01)  // se encontro el pago 
               lImporte  = aTblCargosAbonosLib(cImporte02)  // almacena el importe asociado en la moneda del cargo
               lContinua = false
            FinSi
        FinSi
    FinMientras
    Si lRegresa = 1 Y (aTblDocumento(cTotal)-lImporte) <= 0.01  // si solo hay un pago y el saldo de la factura es 0, entonces es pago en una sola exhibición
        lRegresa = 0
    FinSi
    Retorna lRegresa
FinFunc
// =============================================================================
// fDiscriminaDocto()
// 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 atDocumento(cNaturaleza) != 1 // solo abonos
    lRegresa = 1
  Finsi
  
  Si atDocumento(cUsaCliente) = 0 // solo documentos de clientes
    lRegresa = 1
  Finsi

  Si atDocumento(cEsCFD) != 1   // solo documentos electrónicos
    lRegresa = 1
  Finsi

  Retorna lRegresa

FinFunc

//******************************************************************************
//Encabezado.
Encab
    // Valida el rango de fechas
    pALaFecha = pALaFecha < pDeLaFecha ? pDeLaFecha : pAlaFecha

    // Pone el nombre del sistema
    gFinReporte = 'O'[C0]
    gEmpresa = 'M'[C0]
    ws.Range('A' & RenActual).Font.Color = @RGB(255;0;0)[C0]
    ws.Range('A' & RenActual).Font.Size = 10[C0]
    ws.Range('A' & RenActual).Value = 'AdminPAQ'[C0]
    RenActual = RenActual + 1[C0]

    ws.Range(gFinReporte & RenActual).HorizontalAlignment = xlDerecha[C0]
    ws.Range(gFinReporte & RenActual).Value = gHoy
    RenActual = RenActual + 1[C0]

    // Pone el nombre de la empresa
    ws.Range('A' & RenActual).Font.Size = 14[C0]
    ws.Range('A' & RenActual).Font.Bold = true[C0]
    ws.Range('A' & RenActual & ':' & gEmpresa & RenActual).HorizontalAlignment = xlCentrarEnSeleccion[C0]
    ws.Range('A' & RenActual ).Value = tEmpresa->Nombre

    RenActual = RenActual + 1[C0]

    ws.Range('A' & RenActual).Font.Size = 12[C0]
    ws.Range('A' & RenActual).Font.Bold = true[C0]
    ws.Range('A' & RenActual & ':' & gEmpresa & RenActual).HorizontalAlignment = xlCentrarEnSeleccion[C0]
    ws.Range('A' & RenActual ).Value = 'Documentos Relacionados'[C0]
  
    RenActual = RenActual + 1[C0]
    
    ws.Range('A' & RenActual).Font.Size = 12[C0]
    ws.Range('A' & RenActual).Font.Bold = true[C0]    
    ws.Range('A' & RenActual & ':' & gEmpresa & RenActual).HorizontalAlignment = xlCentrarEnSeleccion[C0]
    gDelaFecha = fFormateaFecha(pDelaFecha;0)
    gAlaFecha  = fFormateaFecha(pAlaFecha;0)
    ws.Range('A' & RenActual ).Value = 'Del: ' & gDelaFecha & ' Al: ' & gAlaFecha[C0]

    RenActual = RenActual + 2[C0]

    ws.Range('A' & RenActual & ':I' & RenActual).HorizontalAlignment = xlCentrarEnSeleccion
    ws.Range('A' & RenActual & ':I' & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple
    ws.Range('A' & RenActual & ':I' & RenActual).Borders(xlSuperior).LineStyle = xlLineaSimple
    ws.Range('A' & RenActual & ':I' & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple
    ws.Range('A' & RenActual & ':I' & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple
    ws.Range('A' & RenActual & ':I' & RenActual).Interior.Color = @RGB(255;0;0) 
    ws.Range('A' & RenActual).Font.Color = @RGB(255;255;255)
    ws.Range('A' & RenActual).Font.Bold = true
    ws.Range('A' & RenActual ).Value = 'RECIBO ELECTRONICO DE PAGO'

    ws.Range('J' & RenActual & ':L' & RenActual).HorizontalAlignment = xlCentrarEnSeleccion
    ws.Range('J' & RenActual & ':L' & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple
    ws.Range('J' & RenActual & ':L' & RenActual).Borders(xlSuperior).LineStyle = xlLineaSimple
    ws.Range('J' & RenActual & ':L' & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple
    ws.Range('J' & RenActual & ':L' & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple
    ws.Range('J' & RenActual & ':L' & RenActual).Interior.Color = @RGB(255;0;0) 
    ws.Range('J' & RenActual).Font.Color = @RGB(255;255;255)
    ws.Range('J' & RenActual).Font.Bold = true
    ws.Range('J' & RenActual ).Value = 'ENCABEZADO XML'

    ws.Range('M' & RenActual & ':O' & RenActual).HorizontalAlignment = xlCentrarEnSeleccion
    ws.Range('M' & RenActual & ':O' & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple
    ws.Range('M' & RenActual & ':O' & RenActual).Borders(xlSuperior).LineStyle = xlLineaSimple
    ws.Range('M' & RenActual & ':O' & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple
    ws.Range('M' & RenActual & ':O' & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple
    ws.Range('M' & RenActual & ':O' & RenActual).Interior.Color = @RGB(255;0;0) 
    ws.Range('M' & RenActual).Font.Color = @RGB(255;255;255)
    ws.Range('M' & RenActual).Font.Bold = true
    ws.Range('M' & RenActual ).Value = 'DOCUMENTO RELACIONADO'

    RenActual = RenActual + 1[C0]

    // Pone el titulo de cada columna en EXCEL
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple[C0]
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlSuperior).LineStyle = xlLineaSimple[C0]
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple[C0]
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple[C0]
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Interior.ColorIndex = 55[C0]    
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Font.Bold = true[C0]    
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Font.Color = @RGB(255;255;255)[C0]
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).WrapText = True
    ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).HorizontalAlignment = xlCentro[C0]	
      
    ws.Range('A' & RenActual).Value = 'UUID del Pago'
    ws.Range('B' & RenActual).Value = 'Serie Pago'
    ws.Range('C' & RenActual).Value = 'Folio Pago'
    ws.Range('D' & RenActual).Value = 'Cuenta Beneficiario'
    ws.Range('E' & RenActual).Value = 'Moneda'
    ws.Range('F' & RenActual).Value = 'Tipo Cambio'
    ws.Range('G' & RenActual).Value = 'Forma Pago'
    ws.Range('H' & RenActual).Value = 'No. de Parcialidad'
    ws.Range('I' & RenActual).Value = 'Importe Pagado'
    ws.Range('J' & RenActual).Value = 'Número Operación'
    ws.Range('K' & RenActual).Value = 'Fecha Pago'
    ws.Range('L' & RenActual).Value = 'Estatus'
    ws.Range('M' & RenActual).Value = 'UUID del Documento'
    ws.Range('N' & RenActual).Value = 'Serie Documento'
    ws.Range('O' & RenActual).Value = 'Folio Documento'
				

    RenActual = RenActual + 1[C0]

    
  FinEncab


//******************************************************************************
//Cuerpo principal.
//******************************************************************************

  tParametros.Busca Primero   

  Si pDeLaCuenta = ' '
    tCuentasFiltro.Busca Primero
    pDeLaCuenta = tCuentasFiltro(cNumeroC01)
  FinSi

  Si pAlaCuenta = ' '
    tCuentasFiltro.Busca Ultimo
    pALaCuenta = tCuentasFiltro(cNumeroC01)
  FinSi


 
  Mientras[tPagos.Busca[pDeLaFecha & '..' & pAlaFecha ]; tPagos->Encontro; tPagos.Busca Siguiente[1]]


    Si fDiscriminaDocto(tPagos) = 1
        Continua
    FinSi

   
    tDigitales.Busca[@STR(tPagos(cIdDocumento);0)]    
    tCuentas.Busca[@STR(tPagos(cIdCuenta);0)]
    tMonedas.Busca[@STR(tPagos(cIdMoneda);0)]

    gImprime = true

    Si tCuentas->ENCONTRO 
       Si tCuentas(cNumeroC01) < pDeLaCuenta O tCuentas(cNumeroC01) > pALaCuenta
           Continua
       FinSi
       ws.Range('D' & RenActual ).Value = @CHR(39) & tCuentas(cNumeroC01)[C0]
    FinSi    

    Si tDigitales->ENCONTRO  // Busca el pago en documentos asociados
       ws.Range('A' & RenActual ).Value = @chr(39) & tDigitales(cUUID)[C0]               
       ws.Range('J' & RenActual ).Value = @chr(39) & tDigitales(CDESCONCBA)[C0]               
       ws.Range('L' & RenActual ).Value = fImprimeEstado(tDigitales(cEstado); tPagos(cCancelado))[C0]    
    FinSi

    ws.Range('B' & RenActual ).Value = tPagos(cSerieDo01)[C0]        
    ws.Range('C' & RenActual ).Value = tPagos(cFolio)[C0]
        

    // Código sat de la moneda del documento
    Si tMonedas->ENCONTRO
       ws.Range('E' & RenActual ).Value = tMonedas(cClaveSAT)[C0]        
    FinSi

    ws.Range('F' & RenActual ).Value = tPagos(cTipoCambio)[C0]        
    ws.Range('G' & RenActual ).Value = fBuscaFormaPago(tPagos(cMetodoPag))[C0]        
    
    ws.Range('K' & RenActual ).Value = @chr(39) & fFormateaFecha(tPagos(cFecha);0)[C0]    
    ws.Range('I' & RenActual ).Value = tPagos(cTotal)[C0]   // se imprime el total del documento, el cual será remplazado si tiene cargos asociados

    Mientras[tCargosAbonos.Busca[@STR(tPagos(cIdDocumento);0)]; tCargosAbonos->Encontro; tCargosAbonos.Busca Siguiente[1]]    
        Si gImprime
            gImprime = false
        SiNo
            Si tCuentas->ENCONTRO 
              ws.Range('D' & RenActual ).Value = @CHR(39) & tCuentas(cNumeroC01)[C0]
            FinSi    

            Si tDigitales->ENCONTRO  // Busca el pago en documentos asociados
                ws.Range('A' & RenActual ).Value = @chr(39) & tDigitales(cUUID)[C0]               
                ws.Range('J' & RenActual ).Value = @chr(39) & tDigitales(CDESCONCBA)[C0]               
                ws.Range('L' & RenActual ).Value = fImprimeEstado(tDigitales(cEstado); tPagos(cCancelado))[C0]    
            FinSi

            ws.Range('B' & RenActual ).Value = tPagos(cSerieDo01)[C0]        
            ws.Range('C' & RenActual ).Value = tPagos(cFolio)[C0]
        

            // Código sat de la moneda del documento
            Si tMonedas->ENCONTRO
                ws.Range('E' & RenActual ).Value = tMonedas(cClaveSAT)[C0]        
            FinSi

            ws.Range('F' & RenActual ).Value = tPagos(cTipoCambio)[C0]        
            ws.Range('G' & RenActual ).Value = fBuscaFormaPago(tPagos(cMetodoPag))[C0]        
    
            ws.Range('K' & RenActual ).Value = @chr(39) & fFormateaFecha(tPagos(cFecha);0)[C0]    
        FinSi

        ws.Range('I' & RenActual ).Value = tCargosAbonos(cImporte01)[C0]                
        
        // Busca el documento que paga
        tDocumentos.Busca[@STR(tCargosAbonos(cIdDocum02);0)]        
        Si tDocumentos->ENCONTRO
            lParcialidad = fNumeroParcialidad(tPagos;tDocumentos;tCargosAbonosLib;tDoctoLib)
            ws.Range('H' & RenActual).HorizontalAlignment = xlCentro[C0]	
            ws.Range('H' & RenActual ).Value = lParcialidad = 0 ? '-':lParcialidad[C0]
            ws.Range('N' & RenActual ).Value = tDocumentos(cSerieDo01)[C0]         
            ws.Range('O' & RenActual ).Value = tDocumentos(cFolio)[C0]
            tDigitalDocto.Busca[@STR(tDocumentos(cIdDocumento);0)]            
            Si tDigitalDocto->ENCONTRO
                ws.Range('M' & RenActual ).Value = @chr(39) & tDigitalDocto(cUUID)[C0]                               
            FinSi
        FinSi
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple[C0]
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple[C0]
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple[C0]
        RenActual = RenActual + 1[C0]
    FinMientras


    Si gImprime 
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlInferior).LineStyle = xlLineaSimple[C0]
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlIzquierda).LineStyle = xlLineaSimple[C0]
        ws.Range('A' & RenActual & ':' & gFinReporte & RenActual).Borders(xlDerecha).LineStyle = xlLineaSimple[C0]    
        RenActual = RenActual + 1[C0]
    FinSi
    
  FinMientras  
  
    //  FIN DEL REPORTE

