// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//	Series.rpt
//	Nombre del reporte en el sistema: Números de serie
//
//  Sistema: AdminPAQ v1.1
// 
//	Este reporte perteneciente al módulo de inventarios, despliega los 
//  movimientos de entrada y salida de series de productos. 
//
//	Consideraciones especiales:
//  
//	Elaboró:    Eduardo Pérez Figueroa
//	Fecha: 	    12 de Septiembre del 2001
//
//  Historia de revisiones:
//	Autor:
//	Fecha:
//
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 08/02/2002   MOFM    SC 22       Se agregaron los parámetros pSeleccionNumeroSerie,
//                                  pNumeroSerie y pEstadoSerie.
//                                  Se modificaron los métodos: fProcesaProducto 
//                                  y el cuerpo del reporte.
// 14/05/2002   CILA    SC 41       Se agrego la implementación de la impresión
//                                  de series, cuando el producto tiene manejo 
//                                  de caracteristicas.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

Incluye LibAdminPAQ.Rpt
Incluye LibInventarios.Rpt


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

Parametro pFechaInicial = '20020501'    // Fecha inicial del rango
Parametro pFechaFinal = '20020531'      // Fecha final del rango
Parametro pProductoInicial = ' '        // Código del producto inicial del rango (' ' = Todos)
Parametro pProductoFinal = ' '          // Código del producto final del rango (' ' = Todos)
Parametro pImprimirProductos = 0        // Productos a imprimir:
                                        // 0 = Todos
                                        // 1 = Solo productos con movimientos 
Parametro pEstadoProducto = 0           // Incluir productos con estado:
                                        // 0 = Todos
                                        // 1 = Activos
                                        // 2 = Inactivos
Parametro pSeleccionNumeroSerie = 0     // 0 = Todos
                                        // 1 = Seleccionar Número de Serie
Parametro pNumeroSerie = '001'          // Número de serie seleccionado
Parametro pEstadoSerie = 0              // 0 = Todos
                                        // 1 = Disponible
                                        // 2 = Consignada del Proveedor
                                        // 3 = No Disponible
                                        // 4 = Huérfana
                                        // 5 = Huérfana Consignada
                                        // 7 = Vendida
                                        // 8 = Consignada
                                        // 9 = Huérfana Devuelta
                                        //10 = Huérfana Consignada Devuelta 
                                        //11 = Consignada Proveedor y luego Vendida
                                        //12 = Consignada Proveedor y luego Consignada
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 tDetalleProducto = tEmpresa['MGW10004']      // Productos Identificador
tDetalleProducto.Usaindice['iProdPadreValoresCarac']  // cIdProductoPadre+cIdValorCaracteristica1..3

UsaTabla tDocumento = tEmpresa['MGW10008']            // Documentos
tDocumento.Usaindice['']                              // Indice primario: cIdDocumento

UsaTabla tMovimiento = tEmpresa['MGW10010'] Alias 'Movto'       // Movimientos
tMovimiento.Usaindice['']                             // Indice primario: cIdMovimiento

UsaTabla tMovtoOwner = tEmpresa['MGW10010'] Alias 'MovtoOwner'  // Movimientos
tMovtoOwner.Usaindice['']                             // Indice primario: cIdMovimiento

UsaTabla tSerie = tEmpresa['MGW10032']                // Series
tSerie.Usaindice['iProdAlmacenSerie']                 // cIdProducto+cIdAlmacen+cNumeroSerie

UsaTabla tMovimientoSerie = tEmpresa['MGW10036']      // Movimientos de series
tMovimientoSerie.Usaindice['iSerieFecha']             // cIdSerie+cFecha

UsaTabla tConcepto = tEmpresa['MGW10006']             // Conceptos de documentos
tConcepto.Usaindice['']                               // Indice primario: cIdConceptoDocumento

UsaTabla tAlmacen = tEmpresa['MGW10003']              // Almacenes
tAlmacen.Usaindice['']                                // Indice primario: cIdAlmacen

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

UsaTabla tCaracteristica = tEmpresa['MGW10021']       // Características
tCaracteristica.Usaindice['']                         // Indice primario: cIdPadreCaracteristica

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

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


// *****************************************************************************
// 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 serie) = 20 caracteres
// C2 (Estado) = 14 caracteres
// C4 (Fecha) = 11 caracteres
// C6 (Serie) = 5 caracteres
// C8 (Folio) = 8 caracteres
// C10 (Concepto) = 15 caracteres
// C12 (Almacén) = 3 caracteres
// C14 (Fecha) = 11 caracteres
// C16 (Serie) = 5 caracteres
// C18 (Folio) = 8 caracteres
// C20 (Concepto) = 15 caracteres
// C22 (Almacen) = 3 caracteres
Columnas 24;2.99,0.15,2.09,0.15,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0.30,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0

Usaletra 'Arial'
Altura 9
[C6,C8,C16,C18].Decimales 0
[C6,C8,C16,C18].Blanco ''


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

gIdioma = 0               // Idioma del reporte
                          // 0 = Español
                          // 1 = Inglés
gMascarillaProducto = ''  // Mascarilla para el código del producto


// *****************************************************************************
//  fGuardaMovimiento
//
//	Esta función almacena en el buffer de impresión, los datos del
//  movimiento para ser impresos por pares.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fGuardaMovimiento(atMovimiento: Tabla; aImprime)
Local lFechaEditada, lIdDocumento

  // Si el movimiento es de entrada
  Si atMovimiento(cAfectaExistencia) = 1
    // Fecha del movimiento
    lFechaEditada = fFormateaFecha(atMovimiento(cFecha); gIdioma)
    aImprime = @Col(lFechaEditada;0)[C4]

    // lee el documento del movimiento
    Si atMovimiento(cIdDocumento)
      tDocumento.Busca[@Str(atMovimiento(cIdDocumento);0)]
    Sino // es un movimiento oculto
      // Busca el ID del documento en el movimiento owner
      lIdDocumento = fIdDocumentoMovtoOwner(atMovimiento; tMovtoOwner) 
      tDocumento.Busca[@Str(lIdDocumento;0)]
    FinSi
    Si tDocumento->Encontro
      // Serie
      aImprime = tDocumento(cSerieDocumento)[C6]
      // Folio
      aImprime = tDocumento(cFolio)[C8]
      // lee el concepto del documento
      tConcepto.Busca[@Str(tDocumento(cIdConceptoDocumento);0)]
      Si tConcepto->Encontro
        aImprime = tConcepto(cNombreConcepto)[C10]
      FinSi
    FinSi
    tAlmacen.Busca[@Str(atMovimiento(cIdAlmacen);0)]
    Si tAlmacen->Encontro
      aImprime = tAlmacen(cCodigoAlmacen)[C12]
    FinSi
  Sino // Movimiento de salida
    // Fecha del movimiento
    lFechaEditada = fFormateaFecha(atMovimiento(cFecha); gIdioma)
    aImprime = @Col(lFechaEditada;0)[C14]

    // lee el documento del movimiento
    Si atMovimiento(cIdDocumento)
      tDocumento.Busca[@Str(atMovimiento(cIdDocumento);0)]
    Sino // es un movimiento oculto
      // Busca el ID del documento en el movimiento owner
      lIdDocumento = fIdDocumentoMovtoOwner(atMovimiento; tMovtoOwner) 
      tDocumento.Busca[@Str(lIdDocumento;0)]
    FinSi
    Si tDocumento->Encontro
      // Serie
      aImprime = tDocumento(cSerieDocumento)[C16]
      // Folio
      aImprime = tDocumento(cFolio)[C18]
      // lee el concepto del documento
      tConcepto.Busca[@Str(tDocumento(cIdConceptoDocumento);0)]
      Si tConcepto->Encontro
        aImprime = tConcepto(cNombreConcepto)[C20]
      FinSi
    FinSi
    tAlmacen.Busca[@Str(atMovimiento(cIdAlmacen);0)]
    Si tAlmacen->Encontro
      aImprime = tAlmacen(cCodigoAlmacen)[C22]
    FinSi
  FinSi
FinFunc


// *****************************************************************************
//  fGuardaSerie
//
//	Esta función almacena en el buffer de impresión, los datos de la serie
//  para ser impresos con el primer movimiento de la serie.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fGuardaSerie(atSerie: Tabla; aImprime)

  aImprime = atSerie(cNumeroSerie)[C0]
  Escoge atSerie(cEstado)
    Caso 1
      aImprime = 'Disponible'[C2]
    FinCaso
    Caso 2
      aImprime = 'Consig. Prov.'[C2]
    FinCaso
    Caso 3
      aImprime = 'No disponible'[C2]
    FinCaso
    Caso 4
      aImprime = 'Huérfana'[C2]
    FinCaso
    Caso 5
      aImprime = 'H. Remisionada'[C2]
    FinCaso
    Caso 6
      aImprime = 'Inv. físico'[C2]
    FinCaso
    Caso 7
      aImprime = 'Vendida'[C2]
    FinCaso
    Caso 8
      aImprime = 'Remisionada'[C2]
    FinCaso
    Caso 9
      aImprime = 'Huérfana dev.'[C2]
    FinCaso
    Caso 10
      aImprime = 'H. rem. dev.'[C2]
    FinCaso
    Caso 11
      aImprime = 'C. Prov. vend.'[C2]
    FinCaso
    Caso 12
      aImprime = 'C. Prov. Rem.'[C2]
    FinCaso
  FinEscoge  
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 20 caracteres
  // C2 50 caracteres
  Columnas 24; 2.99,0.15,7.47,0

  vImprime = ' '[C0..C23]

  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 24;2.99,0.15,2.09,0.15,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0.30,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0
FinFunc


// *****************************************************************************
//  fImprimeMovimiento
//
//	Esta función imprime los datos del movimiento.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeMovimiento(atMovimiento: Tabla; aImprime)

  // Si el movimiento es de entrada
  Si atMovimiento(cAfectaExistencia) = 1
    // Si los datos de entrada están llenos, imprime el renglón y limpia el buffer
    Si @Col(aImprime;4) != ' ' 
      Lista aImprime
      aImprime = ' '[C0..C23]
    FinSi
    fGuardaMovimiento(atMovimiento; &aImprime)
  Sino // El movimiento es de salida    
    // Si los datos de salida están llenos, imprime el renglón y limpia el buffer
    Si @Col(aImprime;14) != ' ' 
      Lista aImprime
      aImprime = ' '[C0..C23]
    FinSi
    fGuardaMovimiento(atMovimiento; &aImprime)
  FinSi  
FinFunc


// *****************************************************************************
//  fImprimeUltimoRenglon
//
//	Esta función imprime el ultimo renglón de movimentos pares, si es que no 
//  ha sido impreso
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeUltimoRenglon(aImprime)
  
  Si @Col(aImprime;4) != ' ' o @Col(aImprime;14) != ' ' 
    Lista aImprime
  FinSi
FinFunc


// *****************************************************************************
//  fObtieneMascarilla
//
//	Obtiene la mascarilla para el código del producto del archivo de 
//  parámetros.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fObtieneMascarilla()

  // Busca el registro de la empresa
  tParametros.Busca Primero
  Si tParametros->Encontro // Si lo encontró
    gMascarillaProducto = tParametros(cMascarillaProducto) // mascarilla para el código del producto
  FinSi
FinFunc


// *****************************************************************************
//  fImprimeCaracteristicas
//
//	Esta función imprime los valores de la caracteristica del producto
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeCaracteristicas(atProducto: Tabla; atDetalleProducto: Tabla)
local lValorModulo

  // Si el producto no tiene control por características no lo consideres para evitar
	// problemas con paquetes.
  lValorModulo = atProducto(cControlExistencia)
  lValorModulo = lValorModulo % 16  // descarto el bit de Lotes
  lValorModulo = lValorModulo % 8   // descarto el bit de Pedimentos
  lValorModulo = lValorModulo % 4   // descarto el bit de Series

  Si lValorModulo < 2  // quiere decir que el bit de caracteristicas no está en 1
    Retorna
  FinSi
  
  Si atDetalleProducto(cIdValorCaracteristica1) o atDetalleProducto(cIdValorCaracteristica2) o atDetalleProducto(cIdValorCaracteristica3)
    vImprime = ' '[C0..C19]
    lValoresCaracteristicas = ' '

    // Lee los valores de las características
    // Caracteristica 1
    Si atDetalleProducto(cIdValorCaracteristica1)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica1);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = tValorCaracteristica(cValorCaracteristica)
      FinSi
    FinSi

    // Caracteristica 2
    Si atDetalleProducto(cIdValorCaracteristica2)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica2);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = lValoresCaracteristicas & '-' & tValorCaracteristica(cValorCaracteristica)
      FinSi
    FinSi

    // Caracteristica 3
    Si atDetalleProducto(cIdValorCaracteristica3)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica3);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = lValoresCaracteristicas & '-' & tValorCaracteristica(cValorCaracteristica)
      FinSi
    FinSi  

    vImprime = @Col(lValoresCaracteristicas;0)[C1]
  
    // Cambia el ancho de las columnas para la impresión de las caracteristicas
    Columnas 24;0.5,10,0

    Imprime vImprime 

    // Regresa las columnas a su ancho original    
    Columnas 24;2.99,0.15,2.09,0.15,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0.30,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0

  FinSi

FinFunc


// *****************************************************************************
//  fProcesaSeries
//
//  Esta función obtiene los números de serie y movimientos del producto 
//  conforme al rango de fechas del reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 08/02/2002   MOFM    SC 22       La búsqueda sobre tSerie cambia dependiendo 
//                                  de si se muestra un núm. de serie en particular
// 15/10/2002   CILA    SC41        Se creo está función quitando este codigo de 
//                                  de la función fProcesaProducto ya se llama de
//                                  diferentes lugares.
//                                  Se agrego la impresión de las caracteristicas
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaSeries(atProducto: Tabla; aIdProducto; aDatosProducto)
Local lFecha, lImprime, lAlMenosUno, lIdProductoIdentificador

  // No se ha impreso alguna serie
  lAlMenosUno = 0

  // Inicializa id Producto identificador
  lIdProductoIdentificador = 0

  // Si se van a mostrar todas las series
  Si pSeleccionNumeroSerie = 0   
    // Recupera todas las series del producto
    Mientras [ tSerie.Busca[@Str(aIdProducto;0)]; tSerie->Encontro; tSerie.Busca Siguiente[1] ]
      Si pEstadoSerie != 0 // Si no son todas las series
     	  Si pEstadoSerie != tSerie(cEstado)
          Continua
		    FinSi
      FinSi
      // Inicializa el buffer de impresión
      lImprime = ' '[C0..C23]
      // Guarda los datos de la serie en el buffer
      fGuardaSerie(tSerie; &lImprime)
      // Inicializa la Fecha de inicio del rango de fechas del reporte
      lFecha = pFechaInicial 
      // Recorre todas las fechas en el rango de fechas del reporte
      Mientras lFecha <= pFechaFinal
        // Recupera los movimientos de serie del producto a partir de la fecha de inicio del reporte
        tMovimientoSerie.Busca[tSerie(cIdSerie) & ':' & lFecha]
        Mientras tMovimientoSerie->Encontro
           // Lee el movimiento a partir de la serie
          tMovimiento.Busca[@Str(tMovimientoSerie(cIdMovimiento);0)]
          Si tMovimiento->Encontro
            Si tMovimiento(cAfectaExistencia) = 1 o tMovimiento(cAfectaExistencia) = 2
              // Al menos se imprime una serie
              lAlMenosUno = 1
              // Si el producto no ha sido impreso, se imprime
              Si !aDatosProducto
                fImprimeDatosProducto(atProducto)
                aDatosProducto = 1
              FinSi
              // Si el producto maneja caracteristicas se imprime el detalle del mismo
              Si lIdProductoIdentificador != aIdProducto
                // Imprime caracteristicas
                fImprimeCaracteristicas(atProducto; tDetalleProducto)
                // Asigna Id de control
                lIdProductoIdentificador = aIdProducto
              FinSi  
              // Imprime el movimiento
              fImprimeMovimiento(tMovimiento; &lImprime)
            FinSi // tMovimiento(cAfectaExistencia)
          FinSi // tMovimiento->Encontro
          // Busca el siguiente movimiento en la misma fecha
          tMovimientoSerie.Busca Siguiente[2]
        FinMientras // tMovimientoSerie->Encontro
        // Incrementa un día a la fecha
        lFecha = fFechaSiguiente(lFecha)
      FinMientras // lFecha <= pFechaFinal
      // Si el último renglón no ha sido impreso, lo imprime
      fImprimeUltimoRenglon(lImprime)
    FinMientras // tSerie.Busca
  SiNo // Si se va a mostrar sólo alguna serie en especial
    // Recupera todas las series del producto
    Mientras [ tSerie.Busca[pNumeroSerie & ':' & aIdProducto]; tSerie->Encontro; tSerie.Busca Siguiente[2] ]
      Si pEstadoSerie != 0 // Si no son todas las series
     	  Si pEstadoSerie != tSerie(cEstado)
          Continua
		  FinSi
      FinSi
      Si lIdProducto != atProducto(cIdProducto)
        Continua
      FinSi
      // Inicializa el buffer de impresión
      lImprime = ' '[C0..C23]
      // Guarda los datos de la serie en el buffer
      fGuardaSerie(tSerie; &lImprime)
      // Inicializa la Fecha de inicio del rango de fechas del reporte
      lFecha = pFechaInicial 
      // Recorre todas las fechas en el rango de fechas del reporte
      Mientras lFecha <= pFechaFinal
        // Recupera los movimientos de serie del producto a partir de la fecha de inicio del reporte
        tMovimientoSerie.Busca[tSerie(cIdSerie) & ':' & lFecha]
        Mientras tMovimientoSerie->Encontro
           // Lee el movimiento a partir de la serie
          tMovimiento.Busca[@Str(tMovimientoSerie(cIdMovimiento);0)]
          Si tMovimiento->Encontro
            Si tMovimiento(cAfectaExistencia) = 1 o tMovimiento(cAfectaExistencia) = 2
              // Al menos se imprime una serie
              lAlMenosUno = 1
              // Si el producto no ha sido impreso, se imprime
              Si !aDatosProducto
                fImprimeDatosProducto(atProducto)
                aDatosProducto = 1
              FinSi
              // Si el producto maneja caracteristicas se imprime el detalle del mismo
              Si lIdProductoIdentificador != aIdProducto
                // Imprime caracteristicas
                fImprimeCaracteristicas(atProducto; tDetalleProducto)
                // Asigna Id de control
                lIdProductoIdentificador = aIdProducto
              FinSi  
              // Imprime el movimiento
              fImprimeMovimiento(tMovimiento; &lImprime)
            FinSi // tMovimiento(cAfectaExistencia)
          FinSi // tMovimiento->Encontro
          // Busca el siguiente movimiento en la misma fecha
          tMovimientoSerie.Busca Siguiente[2]
        FinMientras // tMovimientoSerie->Encontro
        // Incrementa un día a la fecha
        lFecha = fFechaSiguiente(lFecha)
      FinMientras // lFecha <= pFechaFinal
      // Si el último renglón no ha sido impreso, lo imprime
      fImprimeUltimoRenglon(lImprime)
    FinMientras // tSerie.Busca
  FinSi 
  // Si al menos se imprimió una serie
  Si lAlMenosUno
    Saltalin 2
  FinSi
FinFunc


// *****************************************************************************
//  fProcesaProducto
//
//  Esta función obtiene los números de serie y movimientos del producto 
//  conforme al rango de fechas del reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 08/02/2002   MOFM    SC 22       La búsqueda sobre tSerie cambia dependiendo 
//                                  de si se muestra un núm. de serie en particular
// 15/10/2002   CILA    SC 41       Se quito el código de impresión de las series
//                                  creando la función fProcesaSeries, se agrego
//                                  la implementación de impresión de series 
//                                  para productos con caracteristicas.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaProducto(atProducto: Tabla)
Local lDatosProducto

  Si !pImprimirProductos // Imprimir productos sin importar si tiene o no movimientos?
    fImprimeDatosProducto(atProducto)
    lDatosProducto = 1
  Sino
    // No se han impreso los datos del producto
    lDatosProducto = 0
  FinSi

  lIdProducto = atProducto(cIdProducto) 

  // Si el producto no tiene control por características no lo consideres para evitar
	// problemas con paquetes.
  lValorModulo = tProducto(cControlExistencia)
  lValorModulo = lValorModulo % 16  // descarto el bit de Lotes
  lValorModulo = lValorModulo % 8   // descarto el bit de Pedimentos
  lValorModulo = lValorModulo % 4   // descarto el bit de Series

  Si lValorModulo < 2  // quiere decir que el bit de caracteristicas no está en 1

    // Procesa las series de productos sin caracteristicas
    fProcesaSeries(atProducto; lIdProducto; &lDatosProducto)

  Sino

    // Procesa las series de productos con caracteristicas.
    Mientras [ tDetalleProducto.Busca[@Str(lIdProducto;0)]; tDetalleProducto->Encontro; tDetalleProducto.Busca Siguiente[1] ]

      fProcesaSeries(atProducto; tDetalleProducto(cIdProducto); &lDatosProducto)

    FinMientras
  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}NUMEROS DE SERIE'
	Imprime
	Texto '^@TC{0,0,0}@S{16}Del: ' & fFormateaFecha(pFechaInicial;gIdioma) & ' Al: ' & fFormateaFecha(pFechaFinal;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
  // Modifica el ancho de las columnas
  NEGRITAS FALSE
  Columnas 24;2.99,0.15,2.09,0.15,6.87,0,0,0,0,0,0,0,0,0.30,6.87,0,0,0,0,0,0,0,0,0
  Texto C4;'^--------------------------------- E N T R A D A S ---------------------------------'
  Texto C14;'^---------------------------------- S A L I D A S ----------------------------------'
  Imprime
  Columnas 24;2.99,0.15,2.09,0.15,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0.30,1.64,0.15,0.75,0.15,1.20,0.15,2.24,0.15,0.45,0

  NEGRITAS TRUE
	Texto C0;'Número de serie'
  Texto C2;'Estado serie'
	Texto C4;'Fecha'
	Texto C6;'Serie'
	Texto C8;'^Folio'
	Texto C10;'Concepto'
  Texto C12;'Alm'
	Texto C14;'Fecha'
	Texto C16;'Serie'
	Texto C18;'^Folio'
	Texto C20;'Concepto'
  Texto C22;'Alm'
	Imprime

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

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


// *****************************************************************************
// Cuerpo del reporte

// Verifica el rango de productos del reporte
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 08/02/2002   MOFM    SC 22       Se cambia el índice de tSerie dependiendo de 
//                                  si se muestra un núm. de serie en particular
// 15/05/2002   CILA    SC 41       Se agrego las validaciones para incluir los
//                                  productos con caracteristicas, series y las
//                                  combinaciones con lotes y pedimentos. 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
fVerificaParametros()

// Recupera la mascarilla para el código del producto
fObtieneMascarilla()

// Selecciona alguna serie en especial
Si pSeleccionNumeroSerie != 0
   tSerie.Usaindice['iNumeroSerieProducto']             // cNumeroSerie+cIdProducto
FinSi

// Obtiene los productos en el rango especificado en los parámetros del reporte

Mientras [ tProducto.Busca[pProductoInicial & '..' & pProductoFinal]; tProducto->Encontro; tProducto.Busca Siguiente[1] ]

  // 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 series
  // El campo cControlExistencia es un mapa de bits. Los valores que nos interesa son:
  // 00010 = Caracteristicas  ( 2)
  // 00100 = Series           ( 4)
  // 01000 = Pedimentos       ( 8) 
  // 10000 = Lotes            (16)
  // Las combinaciones posibles para series son:
  // Series = 00100 = 4
  // Caracteristicas-Series = 00110 = 6
  // Series-Pedimentos = 01100 = 12
  // Caracteristicas-Series-Pedimentos = 01110 = 14
  // Series-Lotes = 10100= 20
  // Caracteristicas-Series-Lotes = 10110 = 22
  // Series-Pedimentos-Lotes = 11100 = 28
  // Caracteristicas-Series-Pedimentos-Lotes = 11110 = 30
  Si tProducto(cControlExistencia) != 4 y tProducto(cControlExistencia) != 6 y tProducto(cControlExistencia) != 12 y tProducto(cControlExistencia) != 14 y tProducto(cControlExistencia) != 20 y tProducto(cControlExistencia) != 22 y tProducto(cControlExistencia) != 28 y tProducto(cControlExistencia) != 30
    Continua
  FinSi

  fProcesaProducto(tProducto)

FinMientras

