// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//	Caducas.rpt
//	Nombre del reporte en el sistema: Productos con existencias caducas.
//
//  Sistema: AdminPAQ v1.1
// 
//	Este reporte perteneciente al módulo de inventarios, despliega los 
//  productos con lotes cuya fecha de caducidad sea menor a la fecha de
//  corte del reporte.
//
//	Consideraciones especiales:
//  
//	Elaboró:    Eduardo Pérez Figueroa
//	Fecha: 	    14 de Septiembre del 2001
//
//	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/02/2002  Gabriela Cuevas          Se incluyeron totales por producto y por reporte		
// 15/05/2002  MOFM                     Se agregó el manejo de características en productos con
//                                      capas. Se agregaron las tablas  tValoresCaracteristica
//                                      y tProductoDetalle
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

Incluye LibAdminPAQ.Rpt


// *****************************************************************************
//	Parámetros del reporte:

Parametro pFechaCorte = '20030901'      // Fecha de corte o final del reporte
Parametro pProductoInicial = ' '        // Código del producto inicial del rango (' ' = Todos)
Parametro pProductoFinal = ' '          // Código del producto final del rango (' ' = Todos)
Parametro pEstadoProducto = 0           // Incluir productos con estado:
                                        // 0 = Todos
                                        // 1 = Activos
                                        // 2 = Inactivos
Parametro pIdClase1 = 0                 // Clasificaciones del produto (0 = Ninguna)
Parametro pIdClase2 = 0                 // Estos seis parámetros corresponden a las seis clasificaciones
Parametro pIdClase3 = 0                 // del producto, y pueden contener una lista de IDs
Parametro pIdClase4 = 0                 // de clasificaciones separados por coma.
Parametro pIdClase5 = 0               
Parametro pIdClase6 = 0               

// *****************************************************************************
//	Tablas a utilizar e Indices de búsqueda por omisión

UsaEmpresa tEmpresa;'ADMINPAQW'                   // Parámetros

UsaTabla tProducto = tEmpresa['MGW10005']         // Productos
tProducto.Usaindice['iCodigoTipo']                // cCodigoProducto+cTipoProducto

UsaTabla tCapa = tEmpresa['MGW10025']             // Capas
tCapa.Usaindice['iProductoFechaCaducidad']        // cIdProducto+cFechaCaducidad

UsaTabla tSerie = tEmpresa['MGW10032']            // Series
tSerie.Usaindice['iProductoFechaCaducidad']       // cIdProducto+cFechaCaducidad

UsaTabla tValoresDeClasif = tEmpresa['MGW10020']
tValoresDeClasif.UsaIndice['']                    // Indice primario: cIdValorClasificacion

UsaTabla tParametros = tEmpresa['MGW10000']       // Parámetros de la empresa
tParametros.Usaindice['']                         // Indice primario: cIdEmpresa

UsaTabla tProductoDetalle = tEmpresa['MGW10004']       // Producto Detalles
tProductoDetalle.Usaindice['iProdPadreValoresCarac']   // cIdProductoPadre+cIdValorCaracteristica1+cIdValorCaracteristica2+cIdValorCaracteristica3

UsaTabla tValoresCaracteristica = tEmpresa['MGW10022']       // Valores de característica
tValoresCaracteristica.Usaindice['']                         // Indice primario: cIdValorCaracteristica


// *****************************************************************************
// Definiciones y asumidos globales para el reporte

// Ancho de columnas = caracteres / 17 * 2.54
// Se consideran columnas intermedias de un espacio
// C0 (Número de lote) = 20 caracteres
// C2 (Fecha de fabricación) = 11 caracteres
// C4 (Fecha de caducidad) = 11 caracteres
// C6 (Disponible) = 10 caracteres
Columnas 8;2.99,1.49,1.64,1.49,1.64,1.49,1.49,0.15

Usaletra 'Arial'
Altura 9


// *****************************************************************************
//	Variables de ámbito global:

gIdioma = 0               // Idioma del reporte
                          // 0 = Español
                          // 1 = Inglés
gAlMenosUno = 0           // Se desplegó al menos un producto?
gProdImpreso = 0          // El producto actual del rango fue impreso?
gMascarillaProducto = ''  // Mascarilla para el código del producto
gTotalProducto = 0.00
gTotalReporte  = 0.00

// *****************************************************************************
//  fConfiguraDecimales
//
//	Configura el número de decimales de las columnas de importes, basado en
//  en los parámetros de la empresa.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fConfiguraDecimales()

  // Busca el registro de la empresa
  tParametros.Busca Primero
  Si tParametros->Encontro // Si lo encontró
    [C6].Decimales tParametros(cDecimalesUnidades)
    gMascarillaProducto = tParametros(cMascarillaProducto) // mascarilla para el código del producto
  Sino // Si no encontró el registro de la empresa
    [C6].Decimales 2
  FinSi
FinFunc


// *****************************************************************************
//  fImprimeDatosProducto
//
//	Esta función imprime los datos del producto (código, nombre)
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeDatosProducto(atProducto: Tabla)
Local vImprime, lCodigoEditado

  // Redefine el ancho de las columnas
  // C0 29 caracteres
  // C2 40 caracteres
  Columnas 8; 4.33,0.15,5.98,0

  vImprime = ' '[C0..C7]

  NEGRITAS TRUE

  vImprime = 'Producto: '[C0]
  lCodigoEditado = fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto)
  vImprime = @Col(lCodigoEditado;0)[C2]
  Lista vImprime
  
  vImprime = 'Nombre: '[C0]
  vImprime = atProducto(cNombreProducto)[C2]
  Lista vImprime

  SaltaLin

  NEGRITAS FALSE

  // Regresa las columnas a su ancho original    
  Columnas 8;2.99,1.49,1.64,1.49,1.64,1.49,1.49,0.15
FinFunc

// *****************************************************************************
//  fImprimeTotales
//
//	Esta función imprime los totales
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotales(aTotales; aGranTotal)
Local vImprime, lFechaEditada

  vImprime = ' '[C0..C7]

	Si !aGranTotal
		Texto C6;'@L{6}'
		Imprime
	SiNo
		lSubRaya = ''
		lSubRaya = '================='[C6]
		Imprime lSubRaya
	FinSi

  vImprime = @Col(aTotales;0)[C6]
  Lista vImprime
	SaltaLin
FinFunc
// *****************************************************************************
//  fImprimeLote
//
//	Esta función imprime los datos del lote.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeLote(atCapa: Tabla)
Local vImprime, lFechaEditada

  vImprime = ' '[C0..C7]

  // Número de lote
  vImprime = atCapa(cNumeroLote)[C0]
  // Fecha de caducidad
  lFechaEditada = fFormateaFecha(atCapa(cFechaCaducidad); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C2]
  // Fecha de fabricación
  lFechaEditada = fFormateaFecha(atCapa(cFechaFabricacion); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C4]
  // Existencia
  vImprime = atCapa(cExistencia)[C6]
  //N.D. 8081 si no tiene existencias caducas que no muestre nada.
  Si atCapa(cExistencia) < 0 O atCapa(cExistencia) = 0
	vImprime = ''
	gTotalProducto = ''
	gTotalReporte = gTotalReporte + 0
  SiNo
	gTotalProducto = gTotalProducto + @Col(vImprime;6)
	gTotalReporte  = gTotalReporte  + @Col(vImprime;6)
  FinSi
  Lista vImprime
FinFunc

// *****************************************************************************
//  fImprimeCaracteristica
//
//	 Esta función imprime las características y valores de características del producto
//
//  Parámetros IdValorCaracterística1, IdValorCaracterística2 y IdValorCaracteristica3
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fImprimeCaracteristica(aIdValorCaracteristica1; aIdValorCaracteristica2; aIdValorCaracteristica3)
Local vValorCaracteristica1, vValorCaracteristica2, vValorCaracteristica3 

  Si aIdValorCaracteristica1 > 0 
    // Se busca el valor de característica 1  
    tValoresCaracteristica.Busca[@Str(aIdValorCaracteristica1;0)]
    Si tValoresCaracteristica->Encontro
      // Se obtiene el valor de característica con una logitud de 20 caracteres, 
      // eliminando los espacio de la derecha
      vValorCaracteristica1 = @SubStr(tValoresCaracteristica(cValorCaracteristica);0;20) 
      vValorCaracteristica1 = @TRIM(2;vValorCaracteristica1) 
    Finsi
  Sino
    vValorCaracteristica1 = ''    
  Finsi  

  Si aIdValorCaracteristica2 > 0 
    // Se busca el valor de característica 1  
    tValoresCaracteristica.Busca[@Str(aIdValorCaracteristica2;0)]
    Si tValoresCaracteristica->Encontro
      // Se obtiene el valor de característica con una logitud de 20 caracteres, 
      // eliminando los espacio de la derecha
      vValorCaracteristica2 = @SubStr(tValoresCaracteristica(cValorCaracteristica);0;20) 
      vValorCaracteristica2 = @TRIM(2;vValorCaracteristica2) 
    Finsi
  Sino
    vValorCaracteristica2 = ''    
  Finsi  

  Si aIdValorCaracteristica3 > 0 
    // Se busca el valor de característica 1  
    tValoresCaracteristica.Busca[@Str(aIdValorCaracteristica3;0)]
    Si tValoresCaracteristica->Encontro
      // Se obtiene el valor de característica con una logitud de 20 caracteres, 
      // eliminando los espacio de la derecha
      vValorCaracteristica3 = @SubStr(tValoresCaracteristica(cValorCaracteristica);0;20) 
      vValorCaracteristica3 = @TRIM(2;vValorCaracteristica3) 
    Finsi
  Sino
    vValorCaracteristica3 = ''    
  Finsi  
   
  Si aIdValorCaracteristica1 > 0 y aIdValorCaracteristica2 > 0 y aIdValorCaracteristica3 > 0
    Texto vValorCaracteristica1 & '-' & vValorCaracteristica2 & '-' & vValorCaracteristica3
    Imprime vTexto 
  Sino 
     Si aIdValorCaracteristica1 > 0 y aIdValorCaracteristica2 >0 y aIdValorCaracteristica3 = 0
       Texto vValorCaracteristica1 & '-' & vValorCaracteristica2
       Imprime vTexto 
     Sino
       Si aIdValorCaracteristica1 > 0 y aIdValorCaracteristica = 0 y aIdValorCaracteristica3 = 0
         Texto vValorCaracteristica1
         Imprime vTexto 
       Finsi      
     Finsi
   Finsi 

FinFunc


// *****************************************************************************
//  fImprimeSerie
//
//	Esta función imprime los datos del lote cuando el producto tiene series.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeSerie(atSerie: Tabla)
Local vImprime, lFechaEditada

  vImprime = ' '[C0..C7]

  // Número de lote
  vImprime = atSerie(cNumeroLote)[C0]
  // Fecha de caducidad
  lFechaEditada = fFormateaFecha(atSerie(cFechaCaducidad); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C2]
  // Fecha de fabricación
  lFechaEditada = fFormateaFecha(atSerie(cFechaFabricacion); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C4]
  // Existencia
  // Si la serie está disponible o consignada del proveedor, la existencia es uno
  Si atSerie(cEstado) = 1 o atSerie(cEstado) = 2
    vImprime = 1.0[C6]
  Sino // de otra forma la existencia es cero
    vImprime = 0.0[C6]
  FinSi  
	gTotalProducto = gTotalProducto + @Col(vImprime;6)
	gTotalReporte  = gTotalReporte  + @Col(vImprime;6)
  Lista vImprime
FinFunc


// *****************************************************************************
//  fProcesaProducto
//
//  Esta función obtiene los lotes del producto cuya fecha de caducidad es
//  menor a la fecha del reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/05/2002   MOFM                Dependiendo de si el productos que maneja
//                                  capas tiene características se agrega la   
//                                  impresión de las mismas
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaProducto(atProducto: Tabla; aTieneCaracteristicas)
Local lDatosProducto

  // No se han impreso los datos del producto
  lDatosProducto = 0

  Si aTieneCaracteristicas
    Mientras [tProductoDetalle.busca[@Str(tProducto(cIdProducto);0)];tProductoDetalle->encontro;tProductoDetalle.Busca Siguiente[1]]
      // Recupera todas las capas del producto
      Mientras [ tCapa.Busca[@Str(tProductoDetalle(cIdProducto);0)]; tCapa->Encontro; tCapa.Busca Siguiente[1] ]
        // Discrimina capas que no sean de lotes
        Si tCapa(cTipoCapa) != 3 y tCapa(cTipoCapa) != 4
          Continua
        FinSi

        // Si la fecha de caducidad es mayor o igual a la fecha del reporte, descarta la capa
        Si tCapa(cFechaCaducidad) >= pFechaCorte
          FinCiclo
        FinSi

        // Si el producto no ha sido impreso, se imprime
        Si !lDatosProducto
		  Si tCapa(cExistencia) = 0 //N.D.8081 Si no tiene existencias caducas que no se imprime el producto.
			//No se imprime el producto
		  SiNo
			fImprimeDatosProducto(atProducto)
			lDatosProducto = 1
		  FinSi
        FinSi

          fImprimeCaracteristica(tProductoDetalle(cIdValorCaracteristica1);tProductoDetalle(cIdValorCaracteristica2);tProductoDetalle(cIdValorCaracteristica3))

        // Imprime la capa
        fImprimeLote(tCapa)
      FinMientras // tCapa.Busca
    FinMientras
  Sino   
    // Recupera todas las capas del producto
    Mientras [ tCapa.Busca[@Str(atProducto(cIdProducto);0)]; tCapa->Encontro; tCapa.Busca Siguiente[1] ]
      // Discrimina capas que no sean de lotes
      Si tCapa(cTipoCapa) != 3 y tCapa(cTipoCapa) != 4
        Continua
      FinSi

      // Si la fecha de caducidad es mayor o igual a la fecha del reporte, descarta la capa
      Si tCapa(cFechaCaducidad) >= pFechaCorte
        FinCiclo
      FinSi

      // Si el producto no ha sido impreso, se imprime
      Si !lDatosProducto
		Si tCapa(cExistencia) = 0 //N.D.-081 Si no tiene existencias caducas que no se imprime el producto
			//No se imprime el producto :P
		SiNo
			fImprimeDatosProducto(atProducto)
			lDatosProducto = 1
		FinSi
      FinSi

      // Imprime la capa
      fImprimeLote(tCapa)
    FinMientras // tCapa.Busca
  Finsi
 
  // Si el producto fue impreso
  Si lDatosProducto
    //Saltalin 2
    gProdImpreso = 1
  FinSi
FinFunc


// *****************************************************************************
//  fProcesaProductoPorSeries
//
//  Esta función obtiene los lotes del producto cuya fecha de caducidad es
//  menor a la fecha del reporte. El proceso se realiza a través de la tabla
//  de series, en lugar de la tabla de capas.
//
//  Parámetros 
//
//  Salidas 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 25/05/2002   LEPC                Dependiendo de si el productos que maneja
//                                  capas tiene características se agrega la   
//                                  impresión de las mismas
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// *****************************************************************************
DefFunc fProcesaProductoPorSeries(atProducto: Tabla; aTieneCaracteristicas)
Local lDatosProducto

  // No se han impreso los datos del producto
  lDatosProducto = 0

  Si aTieneCaracteristicas
    Mientras [tProductoDetalle.busca[@Str(tProducto(cIdProducto);0)];tProductoDetalle->encontro;tProductoDetalle.Busca Siguiente[1]]

      // Recupera todas las capas del producto
      Mientras [ tSerie.Busca[@Str(tProductoDetalle(cIdProducto);0)]; tSerie->Encontro; tSerie.Busca Siguiente[1] ]
        // Si la fecha de caducidad es mayor o igual a la fecha del reporte, descarta la capa
        Si tSerie(cFechaCaducidad) >= pFechaCorte
          FinCiclo
        FinSi
        // Si el producto no ha sido impreso, se imprime
        Si !lDatosProducto
          fImprimeDatosProducto(atProducto)
          lDatosProducto = 1
        FinSi
        fImprimeCaracteristica(tProductoDetalle(cIdValorCaracteristica1);tProductoDetalle(cIdValorCaracteristica2);tProductoDetalle(cIdValorCaracteristica3))

        // Imprime la capa
        fImprimeSerie(tSerie)
      FinMientras // tCapa.Busca


    Finmientras
  Sino 
    // Recupera todas las capas del producto
    Mientras [ tSerie.Busca[@Str(atProducto(cIdProducto);0)]; tSerie->Encontro; tSerie.Busca Siguiente[1] ]
      // Si la fecha de caducidad es mayor o igual a la fecha del reporte, descarta la capa
      Si tSerie(cFechaCaducidad) >= pFechaCorte
        FinCiclo
      FinSi
      // Si el producto no ha sido impreso, se imprime
      Si !lDatosProducto
        fImprimeDatosProducto(atProducto)
        lDatosProducto = 1
      FinSi
      // Imprime la capa
      fImprimeSerie(tSerie)
    FinMientras // tCapa.Busca
  Finsi

  // Si el producto fue impreso
  Si lDatosProducto
    //Saltalin 2
    gProdImpreso = 1
  FinSi
  
FinFunc


// *****************************************************************************
//  fVerificaParametros
//
//  Esta función verifica los parámetros pProductoInicial y pProductoFinal.
//  Si están vacíos toma el primer y último producto de la tabla.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fVerificaParametros()

  // Si el rango inicial es el primer producto, recupera el código del primero
  Si pProductoInicial = ' '
    tProducto.Busca Primero
    Si tProducto->Encontro
      pProductoInicial = tProducto(cCodigoProducto)
    FinSi
  FinSi

  // Si el rango final es el último producto, recupera el código del último
  Si pProductoFinal = ' '
    tProducto.Busca Ultimo
    Si tProducto->Encontro
      pProductoFinal = tProducto(cCodigoProducto)
    FinSi
  FinSi
FinFunc


// *****************************************************************************
// Encabezado del reporte
// *****************************************************************************
Encab
	Texto '@TC{255,0,0}@S{8}AdminPAQ'
	Hoja '"@TC{0,0,0}@S{8}Hoja: '
	Imprime
	Texto '"@TC{0,0,0}@S{8}Fecha: ' & fFormateaFecha(@Hoy();gIdioma)
  Imprime

	Texto '^@TC{0,0,0}@S{22}' & tEmpresa->Nombre
	Imprime

	Texto '^@TC{0,0,0}@S{16}PRODUCTOS CON EXISTENCIAS CADUCAS'
	Imprime
	Texto '^@TC{0,0,0}@S{16}Al: ' & fFormateaFecha(pFechaCorte;gIdioma)
	Imprime

  // Se Revisan las clasificaciones, para recuperarlas e imprimirlas en el encabezado
  fRevisaClases(tValoresDeClasif)

  Saltalin

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

  // Redefine el ancho de las columnas
  Columnas 8;2.99,1.49,3.14,0,3.14,0,1.49,0.15
	Texto C0;'Número de lote'
	Texto C2;'Fecha de caducidad'
	Texto C4;'Fecha de fabricación'
	Texto C6;'^Disponible*'
	Imprime
  // Regresa las columnas a su ancho original    
  Columnas 8;2.99,1.49,1.64,1.49,1.64,1.49,1.49,0.15

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

	NEGRITAS FALSE
	Color @RGB(0;0;0)
	Altura 9
FinEncab


// *****************************************************************************
// Cuerpo del reporte
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/05/2002   MOFM                Dependiendo de si el productos que maneja
//                                  capas tiene características se agrega la   
//                                  impresión de las mismas
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// Configura los decimales del reporte
fConfiguraDecimales()

// Verifica el rango de productos del reporte
fVerificaParametros()
gTotalReporte = 0.00
// Obtiene los productos en el rango especificado en los parámetros del reporte
Mientras [ tProducto.Busca[pProductoInicial & '..' & pProductoFinal]; tProducto->Encontro; tProducto.Busca Siguiente[1] ]

  // Reinicia
  gProdImpreso = 0
  gTotalProducto = 0.00
  // Solo busca productos, descarta paquetes y servicios
  Si tProducto(cTipoProducto) != 1
    Continua
  FinSi

  // Verifica si el producto es candidato a imprimirse en función de su estado
  // tProducto(cStatusProducto) = 0 (Inactivo)
  // tProducto(cStatusProducto) = 1 (Activo)
  Si pEstadoProducto y pEstadoProducto != @Abs(tProducto(cStatusProducto) - 2)
    Continua
  FinSi

  // Verifica si el producto cumple con las clasificaciones especificadas 
  Si gNumDeClases > 0
    Si !fMiembroDeUnaClase(tProducto; gNumDeClases; gListIdDeClases; 2)
      // Discrimina el producto por no pertenecer a alguna de las clasificaciones
      Continua
    FinSi
  FinSi

  // Discrimina productos cuyo control de existencia es diferente de lotes
  // El campo cControlExistencia es un mapa de bits. Los valores que nos interesa son:
  // 00100 = Series
  // 01000 = Pedimentos
  // 10000 = Lotes
  // Las combinaciones posibles para lotes son:
  // Lotes = 10000 = 16
  // Lotes-Series = 10100 = 20
  // Lotes-Pedimentos = 11000 = 24
  // Lotes-series-pedimentos = 11100 = 28
  // Lotes-Caracteristicas 10010 = 18 
  // Lotes-Pedimentos-Caracteristicas 11010 = 26 
   // nuevas LEPC 23/05/2002
  // Lotes-Unidades = 10001 =17
  // Lotes-Series-Caracteristicas = 10110 = 22
  // Lotes-Pedimentos-Unidades = 11001 = 25
  // Lotes-Caracteristicas-Unidades 10011 = 19 
  // Lotes-Series-Caracteristicas-pedimento = 11110 = 30
  // Lotes-Pedimento-Caracteristicas-Unidades 11011 = 27


  Si tProducto(cControlExistencia) != 16 y tProducto(cControlExistencia) != 20 y tProducto(cControlExistencia) != 24 y tProducto(cControlExistencia) != 28 y tProducto(cControlExistencia) != 18 y tProducto(cControlExistencia) != 26
    Si tProducto(cControlExistencia) != 17 y tProducto(cControlExistencia) != 22 y tProducto(cControlExistencia) != 25 y tProducto(cControlExistencia) != 19 y tProducto(cControlExistencia) != 30 y tProducto(cControlExistencia) != 27
      Continua
    finsi
  FinSi
  // Si el producto tiene series, lo procesa a través de la tabla de series
  Si tProducto(cControlExistencia)  = 12 o tProducto(cControlExistencia)  = 20 o tProducto(cControlExistencia) = 28 o tProducto(cControlExistencia)  = 22 o tProducto(cControlExistencia)  = 14 o tProducto(cControlExistencia)  = 30
    // Si el producto tiene características
    Si tProducto(cBanCaracteristicas) = 1
      fProcesaProductoPorSeries(tProducto;1)
    Sino
      fProcesaProductoPorSeries(tProducto;0)
    Finsi
  Sino // De otra forma, lo procesa por la tabla de capas
    // Si el producto tiene características
    Si tProducto(cBanCaracteristicas) = 1
        fProcesaProducto(tProducto;1) 
    Sino  
      fProcesaProducto(tProducto;0)
    Finsi     
  FinSi

   Si gProdImpreso
      gAlMenosUno = 1
		FImprimeTotales(gTotalProducto; 0)
	FinSi
FinMientras
Si gAlMenosUno
	FImprimeTotales(gTotalReporte; 1)
FinSi

// Si desplegó al menos un producto, despliega el siguiente mensaje
Si gAlMenosUno
  Texto '* Nota: La columna de existencia disponible corresponde a la existencia actual.'
  Imprime
  Texto '  No es la existencia calculada a la fecha del reporte.'
  Imprime
FinSi


