// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//	MovtosSinAfectar.rpt
//	Nombre del reporte en el sistema: Impresión de movimientos sin afectar
//
//  Sistema: AdminPAQ v1.1
// 
//	Este reporte perteneciente al módulo de inventarios, despliega los 
//  movimientos sin afectar de productos. 
//  
//	Elaboró:    Eduardo Pérez Figueroa
//	Fecha: 	    23 de Noviembre del 2001
//
//  Historia de revisiones:
//	Autor:      Eduardo Pérez Figueroa
//	Fecha:      18 de Febrero del 2002
//  No considerar los movimientos de documentos cancelados e incluir total
//  general.
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//  21/05/2007 JAAM     N.C.147     Esquema de adicion de unidades de compra y venta  
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


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

Incluye LibAdminPAQ.Rpt
Incluye LibInventarios.Rpt


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

Parametro pFechaInicial = '20011101'    // Fecha inicial del rango
Parametro pFechaFinal = '20011231'      // 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 = 1        // Productos a imprimir:
                                        // 0 = Todos
                                        // 1 = Solo productos con movimientos 
Parametro pEstadoProducto = 0           // Incluir productos con estado:
                                        // 0 = Todos
                                        // 1 = Activos
                                        // 2 = Inactivos
Parametro pUnidad = 0                   // Unidad de medida y peso para expresar el reporte
                                        // 0 = Unidad base del producto
                                        // 1 = Unidad no equivalente del producto
                                        // 2 = Unidad equivalente (ver parámetro pIdUnidad)
                                        // 3 = Unidad de Compra
                                        // 4 = Unidad de Venta
Parametro pIdUnidad = 2                 // Id de la unidad equivalente
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               

// Acepta 'Fecha inicial [aaaammdd]: ';pFechaInicial
// Acepta 'Fecha final [aaaammdd]: ';pFechaFinal
// Acepta 'Código del producto inicial: ';pProductoInicial
// Acepta 'Código del producto final: ';pProductoFinal

// *****************************************************************************
//	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 tDocumento = tEmpresa['MGW10008']        // Documentos
tDocumento.Usaindice['']                          // Indice primario: cIdDocumento

UsaTabla tMovimiento = tEmpresa['MGW10010'] Alias 'Movto'       // Movimientos
tMovimiento.Usaindice['iProductoFechaAfecta']     // cIdProducto+cFecha+cAfectaExistencia

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

UsaTabla tEjercicio = tEmpresa['MGW10031']        // Ejercicios
tEjercicio.Usaindice['cNumeroEjercicio']          // cNumeroEjercicio

UsaTabla tUnidad = tEmpresa['MGW10026']           // Unidades de peso y medida
tUnidad.Usaindice['']                             // Indice primario: cIdUnidad

UsaTabla tEquivalencia = tEmpresa['MGW10027']     // Equivalencia de unidades de peso y medida
tEquivalencia.Usaindice['']                       // Indice primario: cIdUnidad1+cIdUnidad2

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

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

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

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 (Fecha) = 11 caracteres
// C2 (Serie) = 5 caracteres
// C4 (Folio) = 8 caracteres
// C6 (Concepto) = 25 caracteres
// C8 (Almacen) = 15 caracteres
// C10 (Entradas) = 15 caracteres
// C12 (Salidas) = 15 caracteres
Columnas 14;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.24,0.15,2.24,0.15,2.24,0.15

Usaletra 'Arial'
Altura 9
[C10,C12].Coma
[C2,C4].Decimales 0
[C2,C4].Blanco ''


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

gIdioma = 0               // Idioma del reporte
                          // 0 = Español
                          // 1 = Inglés
// Las siguientes variables se utilizan en el cuerpo principal del reporte
gUnidad = pUnidad         // Almacenamiento del parámetro pUnidad
gIdUnidad = pIdUnidad     // Almacenamiento del parámetro pIdUnidad
gDescUnidad = ''          // Descripción de la unidad de medida o peso
gTotalEntradas = 0.0      // Total de entradas
gTotalSalidas = 0.0       // Total de salidas
gTotalGralEntradas = 0.0  // Total general de entradas
gTotalGralSalidas = 0.0   // Total general de salidas
gDatosProducto = 0        // Bandera que indica si los datos del producto ya fueron impresos
gAlMenosUno = 0           // Se imprimió al menos un producto
gMascarillaProducto = ''  // Mascarilla para el código del producto


// *****************************************************************************
//  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ó
    [C10,C12].Decimales tParametros(cDecimalesUnidades)
    gMascarillaProducto = tParametros(cMascarillaProducto)  // mascarilla para el código del producto
  Sino // Si no encontró el registro de la empresa
    [C10,C12].Decimales 2
  FinSi
FinFunc


// *****************************************************************************
//  fImprimeDatosProducto
//
//	Esta función imprime los datos del producto (código, nombre, método de 
//  costeo y unidad de medida y peso)
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeDatosProducto(atProducto: Tabla)
Local vImprime, lCodigoEditado, lFechaEditada

  // Redefine el ancho de las columnas
  // C0 11 caracteres
  // C1 70 caracteres
  Columnas 14; 2.99,10.46,0.15
  
  vImprime = ' '[C0..C13]

  NEGRITAS TRUE

  vImprime = 'Producto: '[C0]
  lCodigoEditado = fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto)
  vImprime = @Col(lCodigoEditado;0)[C1]
  Lista vImprime
  
  vImprime = 'Nombre: '[C0]
  vImprime = atProducto(cNombreProducto)[C1]
  Lista vImprime
  
  // Imprime unidad de medida y peso
  Escoge pUnidad
    Caso 0 // Unidad base
      tUnidad.Busca[@Str(atProducto(cIdUnidadBase);0)]      
    FinCaso
    Caso 1 // Unidad no equivalente
      tUnidad.Busca[@Str(atProducto(cIdUnidadNoConvertible);0)]        
    FinCaso
    Caso 2 // Unidad equivalente
      tEquivalencia.Busca[atProducto(cIdUnidadBase) & ':' & pIdUnidad]
      Si tEquivalencia->Encontro // Si encontró una equivalencia con la unidad base
        tUnidad.Busca[@Str(pIdUnidad;0)] // Busca la unidad equivalente
      Sino // Si no encontró la unidad equialente, Busca la unidad base
        tUnidad.Busca[@Str(atProducto(cIdUnidadBase);0)]
      FinSi
    FInCaso
  FinEscoge
  Si tUnidad->Encontro y tUnidad(cIdUnidad) != 0 // Encontró el registro de la unidad de medida y peso
    // Guarda la descripción de la unidad en una variable global
    // Así se evita tener que leerla nuevamente al desplegar los totales
    gDescUnidad = tUnidad(cDespliegue) 
    Si gDescUnidad != ''
      vImprime = 'Unidad:'[C0]
      vImprime = @Col(gDescUnidad;0)[C1]
      Lista vImprime
    FinSi
  Sino
    gDescUnidad = ''
  FinSi

  SaltaLin

  NEGRITAS FALSE

  // Regresa las columnas a su ancho original    
  Columnas 14;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.24,0.15,2.24,0.15,2.24,0.15

  // Modifica la variable global que indica que los datos del producto ya fueron impresos
  gDatosProducto = 1
  // Al menos se imprimió un producto
  gAlMenosUno = 1
FinFunc


// *****************************************************************************
//  fImprimeMovimiento
//
//	Esta función imprime los datos de cada movimiento de entrada o salida
//  que se incluye en el reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeMovimiento(atProducto: Tabla; atMovimiento: Tabla; aCostoExistencia)
Local vImprime, lFechaEditada, lIdDocumento


  // Antes de imprimir el movimento, verifica si ya se imprimieron los datos del producto
  Si !gDatosProducto // Si no se han impreso
    // Imprime los datos del producto
    fImprimeDatosProducto(atProducto)
  FinSi

  vImprime = ' '[C0..C13]

  // Fecha del movimiento
  lFechaEditada = fFormateaFecha(atMovimiento(cFecha); gIdioma)
  vImprime = lFechaEditada[C0]

  // 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
    vImprime = tDocumento(cSerieDocumento)[C2]
    // Folio
    vImprime = tDocumento(cFolio)[C4]
    // lee el concepto del documento
    tConcepto.Busca[@Str(tDocumento(cIdConceptoDocumento);0)]
    Si tConcepto->Encontro
      vImprime = tConcepto(cNombreConcepto)[C6]
    FinSi
  FinSi

  // Almacen
  tAlmacen.Busca[@Str(atMovimiento(cIdAlmacen);0)]
  Si tAlmacen->Encontro
    vImprime = tAlmacen(cNombreAlmacen)[C8]
  FinSI

  Si atMovimiento(cAfectaExistencia) = 1 // Entradas
    vImprime = @Col(aCostoExistencia;0)[C10]
    // acumula en el total de entradas del producto
    gTotalEntradas = gTotalEntradas + aCostoExistencia
    // acumula en el total de entradas globales
    gTotalGralEntradas = gTotalGralEntradas + aCostoExistencia
  Sino // Salidas
    vImprime = @Col(aCostoExistencia;0)[C12]
    // acumula en el total de salidas del producto
    gTotalSalidas = gTotalSalidas + aCostoExistencia
    // acumula en el total de salidas globales
    gTotalGralSalidas = gTotalGralSalidas + aCostoExistencia
  FinSi

  Lista vImprime
  
FinFunc


// *****************************************************************************
//  fImprimeTotales
//
//	Esta función imprime los totales por producto.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotales(aEntradas; aSalidas; aDescUnidad)
Local vImprime

	Texto C10;'@L{10}'
	Texto C12;'@L{12}'
	Imprime
  
  vImprime = ' '[C0..C13]
  Si aDescUnidad != '' // Si la descripción de la unidad no está vacía
    vImprime = '^Total en ' & @Col(aDescUnidad;0) & ':'[C6] // imprime la descripción de la unidad
  Sino
    vImprime = '^Total:'[C6]
  FinSi
  vImprime = @Col(aEntradas;0)[C10]
  vImprime = @Col(aSalidas;0)[C12]
  Lista vImprime
  Saltalin 2

FinFunc


// *****************************************************************************
//  fImprimeTotalesGral
//
//	Esta función imprime los totales generales del reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotalesGral(aEntradas; aSalidas)
Local vImprime

	Texto C10;'===================='
	Texto C12;'===================='
	Imprime
  
  vImprime = ' '[C0..C13]
  vImprime = '^Total General:'[C6]
  vImprime = @Col(aEntradas;0)[C10]
  vImprime = @Col(aSalidas;0)[C12]
  Lista vImprime
  Saltalin 2

FinFunc


// *****************************************************************************
//  fProcesaSinCapas
//
//	Esta función lee y procesa los movimientos de entrada y salida cuando el
//  método de costeo es diferente de UEPS o PEPS, es decir, sin capas.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fProcesaSinCapas(atProducto: Tabla)
Local lCostoExistencia, lFecha

  // 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
    // Busca el primer movimiento en esa fecha
    // Si encontro al menos un movimiento, sigue buscando otros movimientos en esa misma fecha
    Mientras [ tMovimiento.Busca[atProducto(cIdProducto) & ':' & lFecha]; tMovimiento->Encontro; tMovimiento.Busca Siguiente[2] ]
      // Discrimina los movimientos sin afectar
      SI tMovimiento(cAfectadoInventario) != 0
        Continua
      FinSi        
      // Discrimina los movimientos que no son entradas ni salidas
      Si tMovimiento(cAfectaExistencia) != 1 y tMovimiento(cAfectaExistencia) != 2
        Continua
      FinSi
      // Discrimina los movimientos de documentos cancelados
      // lee el documento del movimiento
      Si tMovimiento(cIdDocumento)
        tDocumento.Busca[@Str(tMovimiento(cIdDocumento);0)]
      Sino // es un movimiento oculto
        // Busca el ID del documento en el movimiento owner
        lIdDocumento = fIdDocumentoMovtoOwner(tMovimiento; tMovtoOwner) 
        tDocumento.Busca[@Str(lIdDocumento;0)]
      FinSi
      Si tDocumento->Encontro
        Si tDocumento(cCancelado) // El documento está cancelado?
          Continua
        FinSi
      FinSi
      lCostoExistencia = fUnidades(pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tEquivalencia)
      // Imprime el movimiento
      fImprimeMovimiento(atProducto; tMovimiento; lCostoExistencia)
    FinMientras

    // Incrementa un día a la fecha
    lFecha = fFechaSiguiente(lFecha)
  FinMientras
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}IMPRESION DE MOVIMIENTOS SIN AFECTAR'
	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
	Texto C0;'Fecha'
	Texto C2;'Serie'
	Texto C4;'^Folio'
	Texto C6;'Concepto'
	Texto C8;'Almacén'
	Texto C10;'^Entradas'
	Texto C12;'^Salidas'
	Imprime
	Texto '@TC{0,0,0}@L{-1}'
	Imprime 1

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


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

// Inicializa valores globales para la biblioteca LibAdminPAQ.rpt
fIniFechasHistoria(tEjercicio)

// Configura los decimales del reporte
fConfiguraDecimales()

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

// 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

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

  // Inicializa variable para impresión de los datos del producto
  gDatosProducto = 0 // No se han impreso los datos del producto

  // Inicializa variables de totales
  gTotalEntradas = 0.0
  gTotalSalidas = 0.0

  // Verifica parámetro pUnidad
  fVerificaUnidad(tProducto)

  Si !pImprimirProductos // No discriminar productos sin movimientos?
    // Imprime los datos del producto
    fImprimeDatosProducto(tProducto)
  FinSi

  fProcesaSinCapas(tProducto)

  // Se imprimieron los datos del producto?
  Si gDatosProducto
    // Imprime los totales por producto
    fImprimeTotales(gTotalEntradas; gTotalSalidas; gDescUnidad)
  FinSi

  // Regresa el valor original de pUnidad guardado en la variable global gUnidad
  //pUnidad = gUnidad

FinMientras

Si gAlMenosUno
  fImprimeTotalesGral(gTotalGralEntradas; gTotalGralSalidas)
FinSi
