// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Reporte:     Reporte de ventas por producto
//              Reporte de compras por producto
//              Reporte de Notas de Venta por producto
//
// Sistema:     ADMINPAQ  Versión v1.0 Windows
//
// Descripcion: Imprime el total de ventas/compras/devoluciones de un producto en un rango de fechas
//
// Consideraciones :
// Creación  :  Luis Palau Castañeda.  12/Agosto/2001
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 16/05/2007   JAAM    N.C.147     Esquema de adicion de unidades de compra y venta  
// 07/01/2010   ELVS    N.D.6142    Reportes - ERROR AL EJECUTAR EL REPORTE DE VENTAS
//                                  POR PRODUCTO Y SELECCIONAR EL ULTIMO CODIGO CON LA
//                                  OPCION DE REPORTES SENSIBLES DE CONTEXTO, NO 
//                                  ARROJA INFORMACION. 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// *************************************************************************************************
// INCLUSION DE ARCHIVOS
// *************************************************************************************************
    Incluye LibAdminPaq.rpt


// *********************************************************************************************
// INICIO PARAMETROS
// *************************************************************************************************
    Parametro pFechaInicial    = '20050401'  // Fecha inicial del rango
    Parametro pFechaFinal      = '20050430'  // Fecha final del rango
    Parametro pProductoInicial = '(Ninguno)'
    Parametro pProductoFinal   = 'z'
    Parametro pUnidad          = 0  // 0 = Unidad Base  1 = Unidad No Equivalente  2 = Seleccionar Unidad
                                    // 3 = Unidad de Compra   4 = Unidad de Venta  
    Parametro pIdUnidad        = 1  // Id de la unidad del reprote
    Parametro pIdMoneda        = 1  // 1 = ID moneda Peso mexicano
    Parametro pTipoReporte     = 1  // 1  ventas 
                                    // 2  compras
                                    // 3  Notas de Venta
                                    // 4  Devoluciones de Notas de Venta
    Parametro pIdClase1   = 0
    Parametro pIdClase2   = 0
    Parametro pIdClase3   = 0
    Parametro pIdClase4   = 0
    Parametro pIdClase5   = 0
    Parametro pIdClase6   = 0 //Clasificaciones

// *********************************************************************************************
// INICIO APERTURA TABLAS
// *************************************************************************************************
  UsaEmpresa tEmpresa;'AdminpaqW'

  UsaTabla tParametros = tEmpresa['mgw10000']                    

  UsaTabla tProductos = tEmpresa['mgw10005'] Alias 'Productos'
  tProductos.Usaindice['iCodigoTipo']

  UsaTabla tMovimientos = tEmpresa['mgw10010'] Alias 'Movimientos'
  tMovimientos.Usaindice['iProductoDoctoDeAfecFecha']

  UsaTabla tMovimientosDestino = tEmpresa['mgw10010'] Alias 'MovtoDestino'
  tMovimientosDestino.Usaindice['cIdMovtoOrigen']     // cIdMovtoOrigen

  UsaTabla tMovtoOwner = tEmpresa['MGW10010'] Alias 'MovtoOwner'
  tMovtoOwner.Usaindice['']

  UsaTabla tDocumentos = tEmpresa['mgw10008']
  tDocumentos.Usaindice['cIdDocumento']

  UsaTabla tUnidadesPM = tEmpresa['mgw10026']
  tUnidadesPM.Usaindice['']

  UsaTabla tEquivaleUnidadesPM = tEmpresa['mgw10027']
  tEquivaleUnidadesPM.Usaindice['']

  UsaTabla tMonedas = tEmpresa['mgw10034']
  tMonedas.Usaindice['']

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

  UsaTabla tProductosBusqueda = tEmpresa['mgw10005'] Alias 'ProdBusqueda'
  tProductosBusqueda.Usaindice['']

  UsaTabla tClasificaciones = tEmpresa['mgw10020']
  tClasificaciones.Usaindice['']

  UsaTabla tClientes = tEmpresa['mgw10002']
  tClientes.Usaindice['']

  tParametros.Busca Primero   

// *************************************************************************************************
// DEFINICION DE COLUMNAS 
// *************************************************************************************************
  //                 Nombre
  //        Código (Producto) Cantidad   Unidad     Neto   Descuentos Neto-Desc. Impuestos  Total
  //          C0       C2        C4        C6        C8        C10       C12       C14       C16
  Columnas 19;2.7,0.15,4.50,0.15,1.95,0.15,0.45,0.15,1.95,0.15,1.95,0.15,1.95,0.15,1.95,0.15,1.95,0

  UsaLetra 'Arial'
  Altura 9 
  [C0..C7].Decimales 0
  [C0..C7].Blanco ' '
  tMonedas.Busca[@str(pIdMoneda;0)]
  gDecimales = tMonedas(cDecimalesMoneda)
  [C8..C16].Coma
  [C4].Decimales tParametros(cDecimalesUnidades) // Decimales para unidades
  [C8..C16].Decimales gDecimales
  [C4, C8..C16].Blanco '0.00'
  [C9,C11,C13,C15,C17].Blanco ' '


// *************************************************************************************************
// VARIABLES GLOBALES 
// *************************************************************************************************
  gUnidad = pUnidad
  gIdUnidad = pIdUnidad
  gTotalGral = ''
  gTotalProd = ''
  gTotalPaquetes = ''
  gNombreMoneda = tMonedas(cNombreMoneda)
 
  kMeses = 'Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic'[C0]

// FUNCIONES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// =================================================================================================
// Función área sensible al contexto
// =================================================================================================
DefFunc ContextoDetalleProducto(aNumeroColumna; aValor)
    EJECUTA tEmpresa->SysDirDatos & '\Reportes\AdminPAQ\ResProd.rtw';0,0,@Trim(2;@Escoge(aValor;0)),@Trim(2;@Escoge(aValor;0)),@Escoge(aValor;1),@Escoge(aValor;2),pIdMoneda,pTipoReporte,pFechaInicial,pFechaFinal;tEmpresa->Directorio
FinFunc

//**************************************************************************************************
// Descripcion: Esta función recibe una fecha con formato ddmmaaaa y la convierte a formato dd/mmm/aaaa
// Entradas :  Fecha : contiene la fecha AAAAMMDD
// Salida :    regresa una cadena con la fecha en formato DD/MMM/AAAA
//**************************************************************************************************
DefFunc fEditaFecha(aFecha)
Local lMes
Local lRegreso

  lMes = @INT(@SubStr(aFecha;4;2))
  lRegreso[0] = @SubStr(aFecha;6;2) & '/' & @Escoge(kMeses;lMes-1) & '/' & @SubStr(aFecha;0;4)
  Retorna lRegreso
FinFunc

//**************************************************************************************************
// Descripcion: imprime los totales generales de las variables gTotalGral
// Entradas :  
// Salida :    
//**************************************************************************************************
DefFunc fTotalGeneral()
Local LTotalLinea

  LTotalLinea = '==========================='[c0]
  Texto c4; @col(LTotalLinea;0)
  Texto c8; @col(LTotalLinea;0)
  Texto c10; @col(LTotalLinea;0)
  Texto c12; @col(LTotalLinea;0)
  Texto c14; @col(LTotalLinea;0)
  Texto c16; @col(LTotalLinea;0)
  imprime
  gTotalGral =''[c0..c3]
  gTotalGral[2] = 'Total General'
  imprime gTotalGral 

  // Impresión del Total de paquetes
  Si @Col(gTotalPaquetes; 4) > 0
    gTotalPaquetes = ''[c0..c3]
    gTotalPaquetes[2] = 'Total Cantidad de Paquetes'
    Imprime gTotalPaquetes
  FinSi
FinFunc

//**************************************************************************************************
// Descripcion: Imprime los totales del producto 
// Entradas :  
// Salida :    
//**************************************************************************************************
DefFunc fTotalProducto(atProductos:TABLA)
  // Solo si la cantidad del producto es mayor a cero se imprime y se acumula
  Si @Col(gTotalProd;4) > 0
    DEFREGION ContextoDetalleProducto
    Si pTipoReporte = 1 O pTipoReporte = 2
      //N.D.6142 Se elimina un espacio en blanco que generaba error al mandar los parámetros en el reporte sensible al contexto
      [C4].REGIONINFO atProductos(cCodigoProducto) & ',' & pUnidad & ',' & pIdUnidad 
    FinSi
    Imprime gTotalProd
    // Acumula a los Totales
    Si atProductos(cTipoProducto) = 2
      // En caso de paquetes acumular las unidades al total de paquetes
      gTotalPaquetes = gTotalPaquetes + gTotalProd[C4]
      // Acumular los restantes importes
      gTotalGral = gTotalGral + gTotalProd[C8,C10,C12,C14,C16]
    Sino
      // Acumular las cantidades
      gTotalGral = gTotalGral + gTotalProd[C4,C8,C10,C12,C14,C16]
    FinSi
  FinSi
  gTotalProd = ''
FinFunc

//**************************************************************************************************
// Descripcion: Esta función regresa el ID del documento del movimiento owner del 
//              movimiento oculto. La razón de ser de ésta función es que los movimientos
//              ocultos no heredan el campo cIdDocumento de su owner.
// Entradas : atMovtoOculto = Movimiento oculto (características, componentes 
//                            o traspasos)
//            atMovtoOwner = Movimiento owner
// Salida :   Id del documento del movimeinto oculto
//**************************************************************************************************
DefFunc fIdDocumentoMovtoOwner(aIdProducto; atMovtoOculto: Tabla; atMovtoOwner: Tabla )
  Si atMovtoOculto(cIdMovtoOwner)
    atMovtoOwner.Busca[@Str(atMovtoOculto(cIdMovtoOwner);0)] // Busca el movimiento owner
    Si atMovtoOwner->Encontro
      aIdProducto = atMovtoOwner(cIdProducto)
      Retorna atMovtoOwner(cIdDocumento)
    FinSi
  FinSi
  aIdProducto = 0
  Retorna 0
FinFunc

// *************************************************************************************************
// Descripcion : Recorre los movimientos afectados o sin afectar de un producto sumándolos a los totales
// Entrada : aAfecInven - Estado de los movimientos
//             0 - Sin afectar
//             1 - Afectado en existenciasy costos
//             2 - Afectado sólo en existencias
//           atMovimientos        - Tabla de movimientos
//           atMovimientosDestino - Tabla de movimientos destino del pedido, remisión...
//           tMovtoOwner          - Movimientos dueños de los movtos ocultos
//           atProductos          - Tabla de productos
//           atDocumentos         - Tabla de documentos
//           atUnidadesPM         - Tabla de unidades
//           atEquivaleUnidadesPM - Tabla de equivalencias de unidades
//           atParametros         - Tabla de parámetros
// *************************************************************************************************
DefFunc fRecorreMovimientos(aAfecInven; atMovimientos:TABLA; atMovimientosDestino:TABLA; atMovtoOwner:TABLA; atProductos:TABLA; atDocumentos:TABLA; atUnidadesPM:TABLA; atEquivaleUnidadesPM:TABLA; atParametros:TABLA)
Local lsihubocambio
Local lIdProducto
Local lIdMonedaCte

  // N.D.4048 Búsqueda de un movimiento del producto a la fecha inicial del reporte
  gFechaBusqueda = pFechaInicial
  // NOTA: Es obligatorio volver a fijar el índice a fin de que las búsquedas parciales funcionen correctamente
  atMovimientos.Usaindice['iProductoDoctoDeAfecFecha']
  atMovimientos.busca[atProductos(cIdProducto) & ':' & vDocumento & ':' & aAfecInven & ':' & gFechaBusqueda]
  Si !atMovimientos->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 atProductos(cIdProducto) = @Val(@SUBSTR(atMovimientos->Llave;0;11))
      Si vDocumento = @Val(@SUBSTR(atMovimientos->Llave;11;11))
        Si aAfecInven = @Val(@SUBSTR(atMovimientos->Llave;22;6))
          Si @SUBSTR(atMovimientos->Llave;28;8) >= pFechaInicial Y @SUBSTR(atMovimientos->Llave;28;8) <= pFechaFinal
            // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro
            gFechaBusqueda = @SUBSTR(atMovimientos->Llave;28;8)
            atMovimientos.busca[atProductos(cIdProducto) & ':' & vDocumento & ':' & aAfecInven & ':' & gFechaBusqueda]
          FinSi
        FinSi
      FinSi
    FinSi        
  FinSi
  
  Mientras atMovimientos->Encontro Y (atMovimientos(cFecha) <= pFechaFinal)
    vCantidad = 0
    vNeto = 0
    vDescuentos = 0
    vTotal = 0

    // Busca el documento del movimiento
    Si atMovimientos(cIdDocumento)  
      atDocumentos.Busca[@Str(atMovimientos(cIdDocumento);0)]
    Sino 
      lIdDocumento = fIdDocumentoMovtoOwner(&lIdProducto; atMovimientos; atMovtoOwner )
      atDocumentos.Busca[@Str(lIdDocumento;0)]
    Finsi

    // Se cambia a la moneda especificada
    lIdMonedaCte = 1
    tClientes.Busca[@Str(atDocumentos(cIdClienteProveedor);0)]
    Si tClientes->Encontro
      lIdMonedaCte = tClientes(cIdMoneda)
    FinSi

    // No imprimir los documentos cancelados
    Si atDocumentos(cCancelado) = 1
      atMovimientos.BUSCA SIGUIENTE[3]
      Continua
    FinSi

    // Si el Producto tiene Unidad de Medida NO Equivalente  "Y" pUnidad = 1
    Si pUnidad = 1 y atProductos(cIdUnidadNoConvertible) != 0
      vCantidad = atMovimientos(cUnidadesNC)
    Sino
      vCantidad =  atMovimientos(cUnidades)
    Finsi

    lsihubocambio =0
    // Convertir la cantidad a la Unidad del Reporte
    Si pUnidad = 2  Y atProductos(cIdUnidadBase) != 0
      // El Producto tiene Unidad de Medida y Peso
      // Unificar vCantidad de acuerdo a la unidad deseada en el reporte.
      atEquivaleUnidadesPM.busca[@str(atProductos(cIdUnidadBase);0) &':'& @str(pIdUnidad;0)]
      Si atEquivaleUnidadesPM->encontro
        vCantidad = vCantidad * atEquivaleUnidadesPM(cFactorConversion)
        lsihubocambio =1
      Finsi
    Finsi

    // Busca nombre de la unidad de medida o peso
    Si  pUnidad = 1 y atProductos(cidUnidadNoConvertible) != 0
      atUnidadesPM.busca[@str(atProductos(cidUnidadNoConvertible);0)]
    Sino
      Si pUnidad = 2 
        Si lsihubocambio = 1
          atUnidadesPM.busca[@str(@col(pIdUnidad;0);0)]
        Sino
          atUnidadesPM.busca[@str(atProductos(cIdUnidadBase);0)]
        Finsi
      Sino
        atUnidadesPM.busca[@str(atProductos(cIdUnidadBase);0)]
      Finsi
    Finsi
    Si atUnidadesPM->encontro
      gTotalProd = atUnidadesPM(cDespliegue)[C6]
      Si @col(gTotalProd;6)='(N)'
        gTotalProd = ''[C6]
      Finsi
    Finsi

    vDescuentos = atMovimientos(cDescuento1) + atMovimientos(cDescuento2) + atMovimientos(cDescuento3) + atMovimientos(cDescuento4) + atMovimientos(cDescuento5)
    vNeto = atMovimientos(cNeto)
    vImpuestos = atMovimientos(cImpuesto1) + atMovimientos(cImpuesto2) + atMovimientos(cImpuesto3) - atMovimientos(cRetencion1) - atMovimientos(cRetencion2)
    vTotal = atMovimientos(cTotal)

    gTotalProd = gTotalProd + @Col(vCantidad;0)[C4]
    vNeto = fCambiarMonedaDoctoAReporte(atDocumentos; tTiposCambio; vNeto; pIdMoneda; lIdMonedaCte)
    gTotalProd = gTotalProd + @Col(vNeto;0)[C8]
    vDescuentos = fCambiarMonedaDoctoAReporte(atDocumentos; tTiposCambio; vDescuentos; pIdMoneda; lIdMonedaCte)
    gTotalProd = gTotalProd + @Col(vDescuentos;0)[C10]
    gTotalProd = gTotalProd + @Col(vNeto;0) - @Col(vDescuentos;0)[C12]
    gTotalProd = gTotalProd + fCambiarMonedaDoctoAReporte(atDocumentos; tTiposCambio; vImpuestos; pIdMoneda; lIdMonedaCte)[C14]
    gTotalProd = gTotalProd + fCambiarMonedaDoctoAReporte(atDocumentos; tTiposCambio; vTotal; pIdMoneda; lIdMonedaCte)[C16]

    atMovimientos.BUSCA SIGUIENTE[3]
  FinMientras  
Finfunc    


// *************************************************************************************************
// ENCABEZADO 
// *************************************************************************************************
Encab
  Texto '@TC{255,0,0}@S{8}AdminPAQ'
  Hoja '"@TC{0,0,0}@S{8}Página: '
  Imprime

  Texto '@TC{0,0,0}@S{8}Moneda: '& gNombreMoneda
  Texto '^@TC{0,0,0}@S{22}' & tEmpresa->Nombre
  Texto '"@TC{0,0,0}@S{8}Fecha: ' & fEditaFecha(@Hoy())
  Imprime

  Si pTipoReporte = 1
    Texto '^@TC{0,0,0}@S{16}' & ' Reporte de Ventas por Producto'
  Sino
    Si pTipoReporte = 2
      Texto '^@TC{0,0,0}@S{16}' & ' Reporte de Compras por Producto'
    Sino
      Si pTipoReporte = 3
         Texto '^@TC{0,0,0}@S{16}' & ' Reporte de Notas de Venta por Producto'
      SiNo
         Texto '^@TC{0,0,0}@S{16}' & ' Reporte de Devoluciones de Notas de Venta por Producto'
      Finsi
    Finsi
  Finsi
  Texto '"@TC{0,0,0}@S{8}Hora: ' & @Hora()
  Imprime

  Texto '^@TC{0,0,0}@S{16}'& 'Del: ' & fEditaFecha(pFechaInicial) & ' al: ' & fEditaFecha(pFechaFinal)
  Imprime 

  NEGRITAS TRUE
  Altura 10
  //                 Nombre
  //        Código (Producto) Cantidad   Unidad     Neto   Descuentos Neto-Desc. Impuestos  Total
  //          C0       C2        C4        C6        C8        C10       C12       C14       C16
  Columnas 19;2.7,0.15,4.50,0.15,1.95,0.15,0.45,0.15,1.95,0.15,1.95,0.15,1.95,0.15,1.95,0.15,1.95,0
  Texto '@TC{0,0,0}@L{-1}'
  Imprime 

  Texto C0;'Código'
  Texto C2;'Nombre (Producto,Servicio,Paquete)'
  Texto C4;'^Cantidad' 
  Texto C6;'' 
  Texto C8;'^Neto'
  Texto C10;'^Descuentos'
  Texto C12;'^Neto-Desc.'
  Texto C14;'^Impuestos'
  Texto C16;'^Total'
  Imprime   

  Texto '@TC{0,0,0}@L{-1}'
  Imprime 

  NEGRITAS FALSE
  Altura 10
  // Se Revisan las clasificaciones, para recuperarlas e imprimirlas en el encabezado
  fRevisaClases(tClasificaciones )
FinEncab


// *************************************************************************************************
// PRINCIPAL <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// *************************************************************************************************
Si pTipoReporte = 1
  vDocumento = 4    
Sino
  Si pTipoReporte = 2
    vDocumento = 19
  Sino
    Si pTipoReporte = 3
      vDocumento = 35 // Nota de Venta
    Sino
      vDocumento = 36 // Devolucion de Nota de Venta
    Finsi
  Finsi
Finsi

gTotalGral = ''
gTotalProd = ''

Si @str(pProductoInicial;0) = ' '
  tProductos.Busca Primero
Sino
  tProductos.Busca [@str(pProductoInicial;0) & ':']
Finsi

Mientras tProductos->Encontro
  si @str(pProductoFinal;0)!=' '
    Si tProductos(cCodigoProducto) > @str(pProductoFinal;0)
      Finciclo
    Finsi 
  Finsi

  Si gNumDeClases > 0
    Si !fMiembroDeUnaClase(tProductos;gNumDeClases;gListIdDeClases;2)
      // salta el producto actual, por no pertenecer a alguna de las clasificaciones
      tProductos.Saltareg[1]
      Continua
    Finsi
  Finsi

  // Si es uno de los servicios para facturar notas de venta no incluirlo
  Si tProductos(cIdProducto) = tParametros(cIdProdu01)
    tProductos.Saltareg[1]
    Continua
  FinSi
  Si tProductos(cIdProducto) = tParametros(cIdProdu02)
    tProductos.Saltareg[1]
    Continua
  FinSi
  Si tProductos(cIdProducto) = tParametros(cIdProdu03)
    tProductos.Saltareg[1]
    Continua
  FinSi
  Si tProductos(cIdProducto) = tParametros(cIdProdu04)
    tProductos.Saltareg[1]
    Continua
  FinSi
  Si tProductos(cIdProducto) = tParametros(cIdProdu05)
    tProductos.Saltareg[1]
    Continua
  FinSi

  gTotalProd = ''
  gTotalProd = fMascarilla(tProductos(cCodigoProducto);tParametros(cMascarillaProducto))[C0]
  gTotalProd = tProductos(cNombreProducto)[C2]
  gTotalProd = 0[C4]
  gTotalProd = 0[C8]
  gTotalProd = 0[C10]
  gTotalProd = 0[C12]
  gTotalProd = 0[C14]

  fVerificaUnidad(tProductos)
  
  // Recorrer los movimientos sin afectar en existencias y costas, afectado y afectado sólo en existencias
  // Se hace en tres llamados distintos porque el índice no permite hacer un sólo recorrido
  fRecorreMovimientos(0; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)
  fRecorreMovimientos(1; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)
  fRecorreMovimientos(2; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)

  // Si el tipo de reporte es de Ventas, entonces tambien se consideran los movimientos de Notas de Venta
  Si pTipoReporte = 1
     vDocumento = 35 // Nota de Venta
     fRecorreMovimientos(0; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)
     fRecorreMovimientos(1; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)
     fRecorreMovimientos(2; tMovimientos; tMovimientosDestino; tMovtoOwner; tProductos; tDocumentos; tUnidadesPM; tEquivaleUnidadesPM; tParametros)
     // Regresamos a Ventas
     vDocumento = 4    
  FinSi
 
  // Enviar la tabla de productos para que valide si se trata de un paquete y acumule al total de paquetes
  fTotalProducto(tProductos)
  tProductos.Saltareg[1]
FinMientras  // Mientras hay productos

// Imprime Totales Generales
fTotalGeneral()

// FIN REPORTE  
