// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//	MovInventarios.rpt
//	Nombre del reporte en el sistema: Movimientos del Inventario
//
//  Sistema: AdminPAQ v1.1
// 
//	Este reporte perteneciente al módulo de inventarios, despliega los 
//  movimentos de entrada y salida de un producto en un almacén. Los datos
//  a desplegar incluyen las unidades, el costo capturado, el costo del 
//  movimiento, precio de venta y total del movimiento.
//
//	Consideraciones especiales:
//  
//	Elaboró:    Eduardo Pérez Figueroa
//	Fecha: 	    29 de Junio del 2001
//
//  Historia de revisiones:
//	Autor:      Eduardo Pérez Figueroa
//	Fecha:      17 de Febrero del 2002
//  Se incluyeron totales generales.
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/03/2002   CILA    SC 35       Se agrego el parametro para saber si se con-
//                                  sideran todos los movimientos, o solo los que
//                                  que estan afectados o que estan sin afectar.
// 14/05/2002   CILA    SC 41       Se agrego la implementación de la impresión
//                                  de series, lotes y pedimentos cuando el 
//                                  producto tiene manejo de caracteristicas.
// 07/06/2002	 LAP		N.D.659		Se elimino un codigo de debug que no deberia
//												estar en el reporte final
//												- fProcesaMovimientos
//
// 26/07/2002   EOD     SC 150      Debido a la SC 150 todos los movtos ahora se
//                                  afectan en línea y se permiten existencias 
//                                  negativas protegiendo al costo. Por lo tanto
//                                  ya no se imprimen movtos sin afectar, de hoy
//                                  en adelante se afectan en línea todos los 
//                                  movimientos y los movimientos no afectados 
//                                  son erroneos. Esta modificación incluye 
//                                  quitar todas las modificaciones efectuadas 
//                                  por la SC 35 y la ND 585
//  Arquitectura        S.C.224     Adición del filtro de Lista de conceptos de
//                                  documentos a imprimir.
//  31/10/2002  LAP     N.D.1477    Ubica el documento al que pertenece el
//                                  movimiento a fin de discriminar el concepto.
//                                  En caso de que el producto con series no 
//                                  maneje lotes ni pedimentos no mostrar dicha
//                                  información.
//                                  - fProcesaMovimientos
//  14/11/2002  DRdA    N.D.1556    Si no se selecciona ningún concepto se debe 
//                                  asumir que se desean ver todos los conceptos.
//                                  - fProcesaMovimientos
//  27/01/2003  LAP     N.D.1377    Los movimientos incompletos de detalles de
//                                  características no se deben de imprimir
//                                  - fProcesaMovimientos
// 28/07/2003   CILA    N.D.2335    Se cambio el numero de decimales de 2 a 4
//                                  para la columna de tipo de cambio.
//                                  - fImprimePedimento,
//                                  - fImprimeSerie.
// 18/09/2003   HVA    N.D.2335    El costo capturado y el costo del movimiento no corresponden cuando
//                                 la moneda del docto y la del reporte no son la 1
//                                  - fObtieneDatosMovimiento
// 28/04/2005   LAP    N.D.3240     Expresar los importes de los documentos en la moneda 
//                                  del reporte. Considerando que los documentos en moneda 
//                                  base tienen el tipo de cambio de la moneda del cliente 
//                                  a la moneda base. Utilizar fCambiarMonedaDoctoAReporte y
//                                  fCambiarMonedaImporteAReporte de LibAdminPAQ.rpt
// 22/08/2005   HVA    N.D.3408     Mostrar el costo capturado aun cuando el concepto este configurado como oculto o escritura
// 17/07/2007   ELVS   N.D.4734     Esquema de adicion de unidades de compra y venta
// 05/02/2008   JENL   N.D.5062     Se cambia el indice iProductoAlmacenFechaAfec por iProductoAlmacenAfecFecha (JENL). 
//                                  Se modifica:
//                                  -fProcesaMovimientos
// 03/12/2008 	ELVS   N.C.224      Se deben considerar los movimientos que están con el 
//                                  campo cAfectadoInventario = 2, se agrega marca y leyenda
//                                  de que esos movimientos están en captura.  
//  16/12/2008 ELVS     N.D.5585    REPORTES DE INVENTARIO - CUANDO EL PRODUCTO ESTA EN 
//                                  CAPTURA. En los reportes de capa el texto de explicación
//                                  aparece incompleto y en otros reportes aparece el error
//                                  pero no que se puede hacer. 
// 16/03/2011   ALRH    N.D.6846    ERROR MODIFICAR EL NOMBRE DE AGENCIA ADUANAL POR ADUANA 
//                                  EN LA VENTANA DE CAPTURA DE PEDIMENTOS PARA QUE SEA IGUAL 
//                                  A LA EMISION DE COMPROBANTES FISCALES DIGITALES YA QUE CAUSA 
//                                  CONFUSION AL MOMENTO DE CAPTURAR LA INFORMACION DE LOS PRODUCTOS 
//                                  DEBE COINCIDIR CON LOS DATOS QUE MENCIONA EL ANEXO 20.
// *****************************************************************************
// Funciones de librería

Incluye LibAdminPAQ.Rpt
Incluye LibInventarios.Rpt


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

Parametro pFechaInicial = '20020101'    // Fecha inicial del rango
Parametro pFechaFinal = '20021231'      // 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 pAlmacenInicial = ' '         // Código del almacén inicial del rango (' ' = Todos)
Parametro pAlmacenFinal = ' '           // Código del almacén final del rango (' ' = Todos)
// S.C.224 Inicio
Parametro pIdConceptos = 0              // Filtro para impresión de determinados conceptos
// S.C.224 Fin
Parametro pImprimirProductos = 0        // Productos a imprimir:
                                        // 0 = Todos
                                        // 1 = Solo productos con movimientos 
// EOD - SC 150 Inicio
// Parametro pAfectado = 0                 // Movimientos a imprimir
                                        // 0 = Todos
                                        // 1 = Afectados
                                        // 2 = Sin Afectar
// EOD - SC 150 Fin
Parametro pEstadoProducto = 0           // Incluir productos con estado:
                                        // 0 = Todos
                                        // 1 = Activos
                                        // 2 = Inactivos
Parametro pCaracteristicas = 1          // Imprimir características de productos
                                        // 0 = No imprimir características
                                        // 1 = Imprimir características
Parametro pSeries = 1                   // Imprimir series de productos
                                        // 0 = No imprimir series
                                        // 1 = Imprimir series
Parametro pLotes = 1                    // Imprimir lotes de productos
                                        // 0 = No imprimir lotes
                                        // 1 = Imprimir lotes
Parametro pPedimentos = 1               // Imprimir pedimentos de productos
                                        // 0 = No imprimir pedimentos
                                        // 1 = Imprimir pedimentos
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               
Parametro pIdMoneda = 1                 // Id de la moneda a expresar el reporte


// *****************************************************************************
//	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
tDetalleProducto.Usaindice['']                    // Indice primario: cIdProducto

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

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

UsaTabla tMovimientoOculto = tEmpresa['MGW10010'] Alias 'MovtoOculto' // Movimientos
tMovimientoOculto.Usaindice['iMovtoOwnerAfectaExist']      // cIdMovtoOwner+cAfectaExistencias

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

UsaTabla tMovtoSinAfectar = tEmpresa['MGW10010'] Alias 'MovtoSinAfectar'  // Movimientos sin afectar
tMovtoSinAfectar.Usaindice['iProductoDoctoDeAfecFecha']    // cIdProducto+cIdDocumentoDe+cAfectadoInventario+cFecha

UsaTabla tCapa = tEmpresa['MGW10025']             // Capas
tCapa.Usaindice['']                               // Indice primario: cIdCapa

UsaTabla tMovimientoCapa = tEmpresa['MGW10028']   // Movimientos de capas
tMovimientoCapa.Usaindice['']                     // Indice primario: cIdMovimiento+cIdCapa

UsaTabla tSerie = tEmpresa['MGW10032']            // Series
tSerie.Usaindice['']                              // Indice primadio: cIdSerie

UsaTabla tMovimientoSerie = tEmpresa['MGW10036']  // Movimientos de series
tMovimientoSerie.Usaindice['']                    // Indice primario: cIdMovimiento+cIdSerie

UsaTabla tCostoHistorico = tEmpresa['MGW10017']   // Costo histórico
tCostoHistorico.Usaindice['iProdAlmacenFecha']    // cIdProducto+cIdAlmacen+cFechaCostoH+cTipoCosto

UsaTabla tMoneda = tEmpresa['MGW10034']           // Monedas
tMoneda.Usaindice['']                             // Indice primario: cIdMoneda

UsaTabla tTiposCambioLib = tEmpresa['MGW10035']       // Tipo de cambio
tTiposCambioLib.Usaindice['iMonedaFecha']             // cIdMoneda+cFecha

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['cCodigoAlmacen']              // cCodigoAlmacen

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

UsaTabla tClienteProveedor = tEmpresa['MGW10002'] // Clientes/Proveedores
tClienteProveedor.Usaindice['']                   // Indice primario: cIdClienteProveedor

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 tValoresDeClasif = tEmpresa['MGW10020']
tValoresDeClasif.UsaIndice['']                    // Indice primario: cIdValorClasificacion

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

UsaTabla tExistencia = tEmpresa['MGW10030']       // Existencia
tExistencia.Usaindice['iProdEjerAlmacenTipo']     // cIdProducto+cIdEjercicio+cIdAlmacen+cTipoExistencia

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 (Cliente/Proveedor) = 14 caracteres
// C10 (Cantidad) = 10 caracteres
// C12 (Costo capturado) = 10 caracteres
// C14 (Costo movimiento) = 12 caracteres
// C16 (Precio de venta) = 10 caracteres
// C18 (Total) = 12 caracteres
//N.C.224
Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00

Usaletra 'Arial'
Altura 9
[C8,C10,C12,C14,C16,C18].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   //N.D.4734 
gDatosProducto = 0      // Bandera que indica si los datos del producto ya fueron impresos
gAlMenosUno = 0         // Bandera que indica que al menos un producto ya fue impreso
gDatosAlmacen = 0       // Bandera que indica si los datos del almacén ya fueron impresos
gProdTotalCantidad = 0.0  // Total de unidades por producto
gProdTotalCosto = 0.0     // Total de costo por producto
gAlmTotalCantidad = 0.0   // Total de unidades por almacén
gAlmTotalCosto = 0.0      // Total de costo por almacén
gTotalCantidad = 0.0      // Total de unidades global
gTotalCosto = 0.0         // Total de costo global
gDecimalesUnidades = 2    // Número de decimales para unidades
gDecimalesMonedaBase = 2  // Número de decimales de la moneda base del sistema
gMascarillaProducto = ''  // Mascarilla para el código del producto
gMascarillaAlmacen = ''   // Mascarilla para el código del almacén
gMascarillaClientes = ''  // Mascarilla para el código del cliente/proveedor


// *****************************************************************************
//  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ó
    [C8,C10].Decimales tParametros(cDecimalesUnidades)
    gDecimalesUnidades = tParametros(cDecimalesUnidades)
    [C12,C14].Decimales tParametros(cDecimalesCostos)
    [C16].Decimales tParametros(cDecimalesPrecioVenta)
    gMascarillaProducto = tParametros(cMascarillaProducto) // mascarilla para el código del producto
    gMascarillaAlmacen = tParametros(cMascarillaAlmacen) // mascarilla para el código del almacen
    gMascarillaClientes = tParametros(cMascarillaClientes) // mascarilla para el código del cliente/proveedor
  Sino // Si no encontró el registro de la empresa
    [C8,C10,C12,C14,C16].Decimales 2
    gDecimalesUnidades = 2
  FinSi

  // Busca los decimales en la moneda
  tMoneda.Busca[@Str(pIdMoneda;0)]
  Si tMoneda->Encontro // Si lo encontró
    [C18].Decimales tMoneda(cDecimalesMoneda)
  Sino // Si no encontró el registro de la empresa
    [C18].Decimales 2
  FinSi

  // Busca el registro de la moneda base del sistema
  tMoneda.Busca['1']
  Si tMoneda->Encontro
    gDecimalesMonedaBase = tMoneda(cDecimalesMoneda)
  Sino // Si no encontró el registro de la moneda
    gDecimalesMonedaBase = 2
  FinSi
FinFunc


// *****************************************************************************
//  fImprimeCaracteristicas
//
//	Esta función imprime las características capturadas del movimiento
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeCaracteristicas(atProducto: Tabla; atDetalleProducto: Tabla; atMovimientoOculto: Tabla; aTextoCaracteristicas)
Local vImprime, lValoresCaracteristicas, lTextoCaracteristicas, lCantidad

  // Redefine las columnas
  Columnas 20;1.64,0.15,2.39,0.15,2.39,0.15,3.14,0.15,1.49,0.15,1.49,0

  // Procesa solo si existen valores de características
  Si atDetalleProducto(cIdValorCaracteristica1) o atDetalleProducto(cIdValorCaracteristica2) o atDetalleProducto(cIdValorCaracteristica3)
    vImprime = ' '[C0..C19]
    lValoresCaracteristicas = ' '
    lTextoCaracteristicas = ' '

    // Lee los valores de las características
    // Caracteristica 1
    Si atDetalleProducto(cIdValorCaracteristica1)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica1);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = tValorCaracteristica(cValorCaracteristica)
        // Verifica si leer el nombre de la caracteristica
        Si !aTextoCaracteristicas
          tCaracteristica.Busca[@Str(tValorCaracteristica(cIdPadreCaracteristica);0)]
          Si tCaracteristica->Encontro
            lTextoCaracteristicas = tCaracteristica(cNombreCaracteristica)
          FinSi
        FinSi
      FinSi
    FinSi

    // Caracteristica 2
    Si atDetalleProducto(cIdValorCaracteristica2)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica2);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = lValoresCaracteristicas & '-' & tValorCaracteristica(cValorCaracteristica)
        // Verifica si leer el nombre de la caracteristica
        Si !aTextoCaracteristicas
          tCaracteristica.Busca[@Str(tValorCaracteristica(cIdPadreCaracteristica);0)]
          Si tCaracteristica->Encontro
            lTextoCaracteristicas = lTextoCaracteristicas & '-' & tCaracteristica(cNombreCaracteristica)
          FinSi
        FinSi
      FinSi
    FinSi

    // Caracteristica 3
    Si atDetalleProducto(cIdValorCaracteristica3)
      tValorCaracteristica.Busca[@Str(atDetalleProducto(cIdValorCaracteristica3);0)]
      Si tValorCaracteristica->Encontro
        lValoresCaracteristicas = lValoresCaracteristicas & '-' & tValorCaracteristica(cValorCaracteristica)
        // Verifica si leer el nombre de la caracteristica
        Si !aTextoCaracteristicas
          tCaracteristica.Busca[@Str(tValorCaracteristica(cIdPadreCaracteristica);0)]
          Si tCaracteristica->Encontro
            lTextoCaracteristicas = lTextoCaracteristicas & '-' & tCaracteristica(cNombreCaracteristica)
          FinSi
        FinSi
      FinSi
    FinSi

    // Imprime características y valores
    // Verifica si se imprime la leyenda 
    Si !aTextoCaracteristicas
      vImprime = @Col(lTextoCaracteristicas;0)[C4]
      // Enciende bandera de que el texto ya fue impreso
      aTextoCaracteristicas = 1
    FinSi
    vImprime = @Col(lValoresCaracteristicas;0)[C6]

    // Cantidad
    lCantidad = fUnidades(pUnidad; atProducto(cIdUnidadBase); pIdUnidad; atMovimientoOculto; tEquivalencia)
    vImprime = @Col(lCantidad;0)[C8]

    Lista vImprime
  FinSi

  //N.C.224
  // Regresa las columnas a sus valores originales
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00

FinFunc


// *****************************************************************************
//  fImprimeEncabezadoLote
//
//	Esta función imprime los datos del encabezado del lote.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeEncabezadoLote()

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0

  Texto C2;'Número de lote'
  Texto C4;'Fecha caducidad'
  Texto C6;'Fabricación'
  Texto C8;'^Cantidad'
  Imprime
  Texto C2;'@L{2}'
  Texto C3;'@L{3}'
  Texto C4;'@L{4}'
  Texto C5;'@L{5}'
  Texto C6;'@L{6}'
  Texto C7;'@L{7}'
  Texto C8;'@L{8}'
  Imprime
  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
FinFunc


// *****************************************************************************
//  fImprimeEncabezadoPedimento
//
//	Esta función imprime los datos del encabezado del pedimento.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeEncabezadoPedimento()

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0

  Texto C2;'Pedimento'
  Texto C4;'Fecha pedimento'
  // N.D. 6846 ALRH
  Texto C6;'Aduana'
  Texto C8;'^Cantidad'
  Texto C10;'^T.C.'
  Imprime
  Texto C2;'@L{2}'
  Texto C3;'@L{3}'
  Texto C4;'@L{4}'
  Texto C5;'@L{5}'
  Texto C6;'@L{6}'
  Texto C7;'@L{7}'
  Texto C8;'@L{8}'
  Texto C9;'@L{9}'
  Texto C10;'@L{10}'
  Imprime
  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
FinFunc


// *****************************************************************************
//  fImprimeEncabezadoSerie
//
//	Esta función imprime los datos del encabezado de la serie.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeEncabezadoSerie()

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0

  Texto C2;'Serie'
  Imprime
	Texto C2;'@L{2}'
  Imprime
  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
FinFunc


// *****************************************************************************
//  fImprimeDatosAlmacen
//
//	Esta función imprime los datos del Almacén (código, nombre).
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeDatosAlmacen(atAlmacen: Tabla)
Local vImprime, lCodigoEditado

  // Redefine el ancho de las columnas
  // C0 20 caracteres
  // C1 50 caracteres
  Columnas 20; 2.99,7.47,0.15
  
  vImprime = ' '[C0..C19]

  vImprime = 'Almacén: '[C0]
  lCodigoEditado = fMascarilla(atAlmacen(cCodigoAlmacen); gMascarillaAlmacen)
  vImprime = @Col(lCodigoEditado;0)[C1]
  Lista vImprime
  
  vImprime = 'Nombre: '[C0]
  vImprime = atAlmacen(cNombreAlmacen)[C1]
  Lista vImprime
  Saltalin
  
  //N.C.224
  // Regresa las columnas a su ancho original    
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00

  // Modifica la variable global que indica que los datos del almacén ya fueron impresos
  gDatosAlmacen = 1
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, vImprimie2, vImprime3, lCodigoEditado, lFechaEditada
Local lFechaSinAfectar, lExistenciaCongelada

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

  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
  
  vImprime = 'Método de costeo: '[C0]
  Escoge atProducto(cMetodoCosteo)
    Caso 1
      vImprime = 'Costo Promedio'[C1]
    FinCaso
    Caso 2
      vImprime = 'Costo Promedio por Almacén'[C1]
    FinCaso
    Caso 3
      vImprime = 'Ultimo Costo'[C1]
    FinCaso
    Caso 4
      vImprime = 'UEPS'[C1]
    FinCaso
    Caso 5
      vImprime = 'PEPS'[C1]
    FinCaso
    Caso 6
      vImprime = 'Costo Específico'[C1]
    FinCaso
    Caso 7
      vImprime = 'Costo Estándar'[C1]
    FinCaso
  FinEscoge
  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 equivalente, Busca la unidad base
        tUnidad.Busca[@Str(atProducto(cIdUnidadBase);0)]
      FinSi
    FInCaso
  FinEscoge
  Si tUnidad->Encontro // Encontró el registro de la unidad de medida y peso
    Si tUnidad(cIdUnidad) y tUnidad(cDespliegue) != ''
      vImprime = 'Unidad:'[C0]
      vImprime = tUnidad(cDespliegue)[C1]
      Lista vImprime
    FinSi
  FinSi

  // EOD - SC 150 Verificar si el producto tiene algún error y sí es así 
  // desplegar el error.
  vImprime = ''

  // Verificar si hay existencias congeladas
  lExistenciaCongelada = fVerificarExistenciaCongelada(atProducto(cIdProducto); 0; tParametros(cIdEjercicioActual); tExistencia)

  // Si no hay existencias congeladas verificar si hay movimientos sin afectar.
  // Cuando hay existencias congeladas no se revisan movimientos sin afectar 
  // porque pueden deberse a dicha existencia congelada
  Si !lExistenciaCongelada
    // Verificar si hay movimientos sin afectar y en que fecha
    lFechaSinAfectar = fVerificarMovtosSinAfectar(atProducto(cIdProducto); tMovtoSinAfectar; tMovtoOwner; tDocumento)
  SiNo  
    vImprime =  'Advertencia:'[C0]
    vImprime =  '*** En proceso de levantamiento de inventario físico'[C1]
    vImprime2 = '*** Se recomienda aplicar el inventario físico'[C1]
    Lista vImprime
    Lista vImprime2
    lFechaSinAfectar = ''
  FinSi

  // Si hay error de costos y no hay movtos sin afectar O
  // el error de costos ocurrió antes de los movtos sin afectar
  // entonces se despliega el error de costos
  Si ( atProducto(cErrorCosto) Y !lFechaSinAfectar) O ( lFechaSinAfectar Y atProducto(cErrorCosto) Y atProducto(cFechaErrorCosto) < lFechaSinAfectar )
    vImprime = 'Error en costos:'[C0]
    Escoge atProducto(cErrorCosto)
      Caso 1
        vImprime =  '*** Captura en desorden de entradas'[C1]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C1]
        vImprime3 = ''
      FinCaso
      Caso 2
        vImprime =  '*** Captura en desorden de salidas'[C1]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C1]
        vImprime3 = ''
      FinCaso
      Caso 3
        vImprime =  '*** Existencias negativas'[C1]
        vImprime2 = '*** Se recomienda registrar las entradas necesarias'[C1]
        vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C1]
      FinCaso
      Caso 4
        vImprime =  '*** Series sin movimiento de entrada'[C1]
        vImprime2 = '*** Se recomienda registrar la entrada de las series pendientes'[C1]
        vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C1]
      FinCaso
      Caso 5
        vImprime =  '*** Series sin costo'[C1]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C1]
        vImprime3 = ''
      FinCaso
    FinEscoge
    lFechaEditada = fFormateaFecha(atProducto(cFechaErrorCosto); gIdioma)
    vImprime = @Col(vImprime;1) & ' a partir del ' & @Col(lFechaEditada;0)[C1]
    Lista vImprime
    Lista vImprime2
    Si vImprime3 
      Lista vImprime3
    FinSi
  FinSi

  // Si hay movtos sin afectar y no hay errores de costos O
  // los movtos sin afectar ocurrieron antes del error de costos
  // entonces se despliega el error de movtos sin afectar
  Si ( lFechaSinAfectar Y !atProducto(cErrorCosto) ) O ( lFechaSinAfectar Y atProducto(cErrorCosto) Y lFechaSinAfectar <= atProducto(cFechaErrorCosto) )
    vImprime = 'Error en costos:'[C0]
    vImprime = '*** Movimientos sin afectar'[C1]
    lFechaEditada = fFormateaFecha(lFechaSinAfectar; gIdioma)
    vImprime = @Col(vImprime;1) & ' a partir del ' & @Col(lFechaEditada;0)[C1]
    vImprime2 = '*** Se recomienda consultar el reporte "Movimientos sin Afectar"'[C1]
    vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C1]
    Lista vImprime
    Lista vImprime2
    Lista vImprime3
  FinSi  // Hay error de movimientos sin afectar
  Saltalin
  // FIN EOD - SC 150

  NEGRITAS FALSE

  //N.C.224
  // Regresa las columnas a su ancho original    
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00

  // Modifica la variable global que indica que los datos del producto ya fueron impresos
  gDatosProducto = 1
  gAlMenosUno = 1
FinFunc


// *****************************************************************************
//  fImprimeLote
//
//	Esta función imprime los datos del lote.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeLote(atCapa: Tabla; atMovimientoCapa: Tabla)
Local vImprime, lFechaEditada

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0

  // Número de lote
  vImprime = atCapa(cNumeroLote)[C2]
  // Fecha de caducidad
  lFechaEditada = fFormateaFecha(atCapa(cFechaCaducidad); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C4]
  // Fecha de fabricación
  lFechaEditada = fFormateaFecha(atCapa(cFechaFabricacion); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C6]
  // Cantidad
  vImprime = atMovimientoCapa(cUnidades)[C8]

  Lista vImprime

  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
FinFunc


// *****************************************************************************
//  fImprimeMovimiento
//
//	Esta función imprime los datos de cada movimiento de entrada o salida
//  que se incluye en el reporte.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/03/2002   CILA    SC 35       Se agrego a la fecha del movimiento el * si
//                                  si este no esta afectado.         
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fImprimeMovimiento(atProducto: Tabla; atMovimiento: Tabla; atAlmacen: Tabla; aCantidad; aCostoCapturado; aCostoMovimiento; aPrecio; aTotal; aTieneMovtosEnCaptura)
Local vImprime, lFechaEditada, lCodigoEditado, lIdDocumento

  // FBCS antes de continuar verifica que el docto no este cancelado
  // 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
    Si tDocumento(cCancelado) = 1   // Esta cancelado??? 
      Retorna                     // No se imprime
    Finsi
  Finsi
  // Fin FBCS 

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

  // También verifica si ya se imprimieron los datos del almacén
  Si !gDatosAlmacen // Si no se han impreso
    // Imprime los datos del producto
    fImprimeDatosAlmacen(atAlmacen)
  FinSi

  vImprime = ' '[C0..C19]

  // Fecha del movimiento
  lFechaEditada = fFormateaFecha(atMovimiento(cFecha); gIdioma)
  // EOD - SC 150 Inicio
  // CILA - SC 35
  //Si atMovimiento(cAfectadoInventario) = 0
  //  lFechaEditada = '*' & lFechaEditada
  //SiNo
  //  lFechaEditada = ' ' & lFechaEditada
  //FinSi 
  // Fin CILA - SC 35
  // EOD - SC 150 Fin
  vImprime = lFechaEditada[C0]

  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
    // Lee el cliente o proveedor
    tClienteProveedor.Busca[@Str(tDocumento(cIdClienteProveedor);0)]
    Si tClienteProveedor->Encontro
      lCodigoEditado = fMascarilla(tClienteProveedor(cCodigoCliente); gMascarillaClientes)
      vImprime = @Col(lCodigoEditado;0)[C8]
    FinSi
  FinSi

  // Cantidad
  vImprime = @Col(aCantidad;0)[C10]
  // Costo capturado
  vImprime = @Col(aCostoCapturado;0)[C12]
  // Costo movimiento
  vImprime = @Col(aCostoMovimiento;0)[C14]
  // Precio de venta
  // Solo si es una salida
  Si atMovimiento(cAfectaExistencia) = 2
    vImprime = @Col(aPrecio;0)[C16]
  FinSi
  // Total (sin impuestos)
  vImprime = @Col(aTotal;0)[C18]

  //N.C.224
  //Si el parámetro de tiene movimientos solo afectados en existencias es verdadero entonces imprime (*)
  Si aTieneMovtosEnCaptura = 1
   vImprime = '(*)'[C20]
  FinSi
  Lista vImprime    
  //Fin N.C.224
	
  // Acumula a los totales
  Si atMovimiento(cAfectaExistencia) = 1 // es una entrada? Suma
    // Acumula a los totales por producto
    gProdTotalCantidad = gProdTotalCantidad + aCantidad
    gProdTotalCosto = gProdTotalCosto + aCostoMovimiento
    // Acumula a los totales por almacén
    gAlmTotalCantidad = gAlmTotalCantidad + aCantidad
    gAlmTotalCosto = gAlmTotalCosto + aCostoMovimiento
    // Acumula a los totales generales
    gTotalCantidad = gTotalCantidad + aCantidad
    gTotalCosto = gTotalCosto + aCostoMovimiento
  Sino // es una salida? resta
    // Acumula a los totales por producto
    gProdTotalCantidad = gProdTotalCantidad - aCantidad
    gProdTotalCosto = gProdTotalCosto - aCostoMovimiento
    // Acumula a los totales por almacén
    gAlmTotalCantidad = gAlmTotalCantidad - aCantidad
    gAlmTotalCosto = gAlmTotalCosto - aCostoMovimiento
    // Acumula a los totales generales
    gTotalCantidad = gTotalCantidad - aCantidad
    gTotalCosto = gTotalCosto - aCostoMovimiento
  FinSi
FinFunc


// *****************************************************************************
//  fImprimePedimento
//
//	Esta función imprime los datos del pedimento.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimePedimento(atCapa: Tabla; atMovimientoCapa: Tabla)
Local vImprime, lFechaEditada

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0
  // N.D.2335 Inicio -----------------------------
  //[C10].Decimales gDecimalesMonedaBase
  [C10].Decimales 4
  // N.D.2335 Fin --------------------------------
  // Número de pedimento
  vImprime = atCapa(cPedimento)[C2]
  // Fecha de pedimento
  lFechaEditada = fFormateaFecha(atCapa(cFechaPedimento); gIdioma)
  vImprime = @Col(lFechaEditada;0)[C4]
  // Agencia aduanal
  vImprime = atCapa(cAduana)[C6]
  // Cantidad
  vImprime = atMovimientoCapa(cUnidades)[C8]
  // Tipo de cambio
  vImprime = atCapa(cTipoCambio)[C10]

  Lista vImprime

  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
  [C10].Decimales gDecimalesUnidades
FinFunc


// *****************************************************************************
//  fImprimeSerie
//
//	Esta función imprime los datos de la serie
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeSerie(atSerie: Tabla; aProceso)
Local vImprime, lFechaEditada

  // Redefine el ancho de las columnas
  Columnas 20;1.64,0.15,3.14,0.15,2.39,0.15,2.39,0.15,1.49,0.15,1.49,0

  vImprime = ' '[C0..C19]

  // Esta función procesa también pedimentos y lotes cuando el producto tiene también series
  Escoge aProceso
    Caso 1 // Series
      vImprime = atSerie(cNumeroSerie)[C2]
    FinCaso
    Caso 2 // Lotes
      // Número de lote
      vImprime = atSerie(cNumeroLote)[C2]
      // Fecha de caducidad
      lFechaEditada = fFormateaFecha(atSerie(cFechaCaducidad); gIdioma)
      vImprime = @Col(lFechaEditada;0)[C4]
      // Fecha de fabricación
      lFechaEditada = fFormateaFecha(atSerie(cFechaFabricacion); gIdioma)
      vImprime = @Col(lFechaEditada;0)[C6]
      // Cantidad
      vImprime = 1.0[C8]
    FinCaso
    Caso 3 // Pedimentos
      // N.D.2335 Inicio -----------------------------
      [C10].Decimales 4
      // N.D.2335 Fin --------------------------------
      // Número de pedimento
      vImprime = atSerie(cPedimento)[C2]
      // Fecha de pedimento
      lFechaEditada = fFormateaFecha(atSerie(cFechaPedimento); gIdioma)
      vImprime = @Col(lFechaEditada;0)[C4]
      // Agencia aduanal
      vImprime = atSerie(cAduana)[C6]
      // Cantidad
      vImprime = 1.0[C8]
      // Tipo de cambio
      vImprime = atSerie(cTipoCambio)[C10]
    FinCaso
  FinEscoge

  Lista vImprime
  //N.C.224
  // Regresa las columnas a su ancho original
  Columnas 21;1.64,0.15,0.75,0.15,1.20,0.15,3.74,0.15,2.09,0.15,1.49,0.15,1.49,0.15,1.79,0.15,1.49,0.15,1.79,0.15,1.00
  // N.D.2335 Inicio -------------------
  [C10].Decimales gDecimalesUnidades
  // N.D.2335 Fin ----------------------
FinFunc


// *****************************************************************************
//  fImprimeTotales
//
//	Esta función imprime los totales por producto o por almacén.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotales(aCualTotal; aCantidad; aCostoMovimiento)
Local vImprime

  Si aCualTotal = 2 // Total por almacén, brinca un renglón
    Saltalin
  FinSi
  Si aCualTotal = 3 // Total general
  	Texto C10;'===================='
	  Texto C14;'===================='
  Sino    
  	Texto C10;'@L{10}'
	  Texto C14;'@L{14}'
  FinSi
	Imprime
  
  vImprime = ' '[C0..C19]
  Si aCualTotal = 1
    vImprime = '^Total Producto:'[C6] 
  Sino
    Si aCualTotal = 2
      vImprime = '^Total Almacén:'[C6] 
    Sino
      vImprime = '^Total General:'[C6] 
    FinSi
  FinSi
  vImprime = @Col(aCantidad;0)[C10]
  vImprime = @Col(aCostoMovimiento;0)[C14]
  Lista vImprime
  Si aCualTotal = 1
    Saltalin 2
  Sino
    Saltalin 1
  FinSi
FinFunc


// *****************************************************************************
//  fObtieneDatosMovimiento
//
//  Esta función obtiene los datos del movimiento para ser impresos en el
//  reporte.
//
//  Parámetros
//
//  Salidas
// *****************************************************************************
DefFunc fObtieneDatosMovimiento(atProducto: Tabla; atMovimiento: Tabla; aCantidad; aCostoCapturado; aCostoMovimiento; aPrecio; aTotal)
Local lTipoCambioDocumento, lGastos, lIdDocumento, lTipoCambio
Local lIdMonedaCliente

  // recupera las unidades del movimiento
  aCantidad = fUnidades(pUnidad; atProducto(cIdUnidadBase); pIdUnidad; atMovimiento; tEquivalencia)

  // Lee el documento del movimiento para obtener el tipo de cambio del documento
  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
  //! N.D.3240 Si tDocumento->Encontro
  //! N.D.3240   lTipoCambioDocumento = tDocumento(cTipoCambio)
  //! N.D.3240 Sino
  //! N.D.3240   lTipoCambioDocumento = 1
  //! N.D.3240 FinSi

  // N.D.3240 Inicio
  // Lee el cliente o proveedor
  tClienteProveedor.Busca[@Str(tDocumento(cIdClienteProveedor);0)]

  // N.D.3240 Id de la moneda del cliente / proveedor
  Si tClienteProveedor->Encontro
    lIdMonedaCliente = tClienteProveedor(cIdMoneda)
  Sino
    lIdMonedaCliente = tDocumento(cIdMoneda)
  FinSi
  // N.D.3240 Fin

  // Obtiene el costo capturado
  // lee el concepto del documento
  // para saber si el costo se captura
  tConcepto.Busca[@Str(tDocumento(cIdConceptoDocumento);0)]

//  Si tConcepto->Encontro y tConcepto(cUsaCostoCapturado) = 4
  Si tConcepto->Encontro y tConcepto(cUsaCostoCapturado) != 1
    // El costo capturado está directamente en el campo
    //! N.D.3240 aCostoCapturado = atMovimiento(cCostoCapturado)
    aCostoCapturado = fCambiarMonedaDoctoAReporte(tDocumento; tTiposCambioLib; atMovimiento(cCostoCapturado); pIdMoneda; lIdMonedaCliente)
  Sino // sino es documento de inventarios o devolución
    // Calcula el costo capturado
    // Si es una entrada se toma del precio, si es una salida entonces es cero
    Si atMovimiento(cAfectaExistencia) = 1
      // Recupera los gastos prorrateados del movimiento
      lGastos = fGastosProrrateados(atMovimiento; tDocumento)
      // Ahora obtiene los gastos prorrateados por unidad
      lGastos = lGastos / atMovimiento(cUnidades)
      //! N.D.3240 // HVA solo cuando la moneda del reporte es diferente a la del documento se debe convertir
      //! N.D.3240 Si pIdMoneda != tDocumento(cIdMoneda)      
      //! N.D.3240    aCostoCapturado = atMovimiento(cPrecio) * lTipoCambioDocumento + lGastos
      //! N.D.3240 Sino
      //! N.D.3240    aCostoCapturado = atMovimiento(cPrecio) + lGastos
      //! N.D.3240 FinSi      
      aCostoCapturado = fCambiarMonedaDoctoAReporte(tDocumento; tTiposCambioLib; atMovimiento(cPrecio); pIdMoneda; lIdMonedaCliente)
      // Los gastos se capturan en la moneda base
      aCostoCapturado = aCostoCapturado + fCambiarMonedaImporteAReporte(tDocumento; tTiposCambioLib; lGastos; 1; pIdMoneda; lIdMonedaCliente)
      // Si el reporte se pidio en unidades no convertibles o equivalentes
      Si pUnidad != 0
        // El costo capturado deberá expresarse en términos de la relación que existe entre la unidad base y la unidad equivalente o no convertible
        aCostoCapturado = aCostoCapturado * atMovimiento(cUnidades) / aCantidad
      FinSi
    Sino
      aCostoCapturado = 0.0
    FinSi
  FinSi // tMovimiento(cIdDocumentoDe) 

  //! N.D.3240 // Se evita mandar llamar a la funcion fCostoMoviento ya que siempre va a buscar a la tabla de 
  //! N.D.3240 // tipos de acumulados y no a la del documento tanto para entradas y como salidas
  //! N.D.3240 Si atMovimiento(cAfectaExistencia) = 1 // es una entrada?
  //! N.D.3240    // Recupera el costo del movimiento
  //! N.D.3240    Si pIdMoneda != 1
  //! N.D.3240       aCostoMovimiento = atMovimiento(cCostoEspecifico) / tDocumento(cTipoCambio)
  //! N.D.3240    Sino
  //! N.D.3240       aCostoMovimiento = atMovimiento(cCostoEspecifico)
  //! N.D.3240    FinSi
  //! N.D.3240 Sino
  //! N.D.3240   Si atProducto(cMetodoCosteo) > 3
  //! N.D.3240     // lCosto = fCostoEspecifico(atMovimiento; atTiposCambioLib; aIdMoneda)
  //! N.D.3240     aCostoMovimiento = atMovimiento(cCostoEspecifico) / tDocumento(cTipoCambio)
  //! N.D.3240   Sino // Costo promedio y último costo, buscar el costo del movimiento de salida en la tabla de costos historicos
  //! N.D.3240     aCostoMovimiento = fCostoMovimiento(atProducto; atMovimiento; tCostoHistorico; tTipoCambio; pIdMoneda)
  //! N.D.3240   FinSi
  //! N.D.3240 FinSi
  // N.D.3240
  // A fin de evitar que los reportes y los acumulados muestren información diferente de costos SIEMPRE se toma el
  //  costo del costo especifico del Movimiento; el cual está en moneda base
  aCostoMovimiento = fCostoEspecifico(atMovimiento; tTiposCambioLib; 1)
  aCostoMovimiento = fCambiarMonedaImporteAReporte(tDocumento; tTiposCambioLib; aCostoMovimiento; 1; pIdMoneda; lIdMonedaCliente)

  // Precio de venta
  // Si es una entrada, entonces el precio de venta es cero, si es una salida se toma del campo
  //! N.D.3240 aPrecio = atMovimiento(cAfectaExistencia) = 1? 0 : atMovimiento(cPrecio) * lTipoCambioDocumento
  Si atMovimiento(cAfectaExistencia) = 1
    aPrecio = 0
  Sino
    aPrecio = fCambiarMonedaDoctoAReporte(tDocumento; tTiposCambioLib; atMovimiento(cPrecio); pIdMoneda; lIdMonedaCliente)
  FinSi
  
  // Recupera el total sin impuestos
  //! N.D.3240 // El total esta expresado en la moneda del docto por lo que solo hay que multiplicarlo por el tipo de cambio si la moneda del reporte
  //! N.D.3240 // es diferente a la del docto
  //! N.D.3240 Si pIdMoneda != tDocumento(cIdMoneda)
  //! N.D.3240    aTotal = (atMovimiento(cNeto) - atMovimiento(cDescuento1) - atMovimiento(cDescuento2) - atMovimiento(cDescuento3) - atMovimiento(cDescuento4) - atMovimiento(cDescuento5)) * lTipoCambioDocumento
  //! N.D.3240 Sino
  //! N.D.3240    aTotal = (atMovimiento(cNeto) - atMovimiento(cDescuento1) - atMovimiento(cDescuento2) - atMovimiento(cDescuento3) - atMovimiento(cDescuento4) - atMovimiento(cDescuento5))
  //! N.D.3240 FinSi
  // N.D.3240
  aTotal = (atMovimiento(cNeto) - atMovimiento(cDescuento1) - atMovimiento(cDescuento2) - atMovimiento(cDescuento3) - atMovimiento(cDescuento4) - atMovimiento(cDescuento5))
  aTotal = fCambiarMonedaDoctoAReporte(tDocumento; tTiposCambioLib; aTotal; pIdMoneda; lIdMonedaCliente)

  //! N.D.3240 // Convierte importes a la moneda del reporte
  //! N.D.3240 // Todos los importes, excepto el costo del movimiento que ya viene expresado en la moneda del reporte
  //! N.D.3240 // aCostoCapturado = fConvierteTipoCambio(aCostoCapturado; 1; pIdMoneda; atMovimiento(cFecha); tTipoCambio)
  //! N.D.3240 // aPrecio = fConvierteTipoCambio(aPrecio; 1; pIdMoneda; atMovimiento(cFecha); tTipoCambio)
  //! N.D.3240 // aTotal = fConvierteTipoCambio(aTotal; 1; pIdMoneda; atMovimiento(cFecha); tTipoCambio)
  //! N.D.3240 Si pIdMoneda != 1 y pIdMoneda != tDocumento(cIdMoneda)
  //! N.D.3240   lTipoCambio = fTipoCambio(atMovimiento(cFecha); pIdMoneda; tTipoCambio)
  //! N.D.3240   aCostoCapturado = aCostoCapturado / lTipoCambio
  //! N.D.3240   aPrecio = aPrecio / lTipoCambio
  //! N.D.3240   aTotal =  aTotal / lTipoCambio
  //! N.D.3240 FinSi
FinFunc

// *****************************************************************************
//  fProcesaSeries
//
//  Esta función lee los movimientos de series a partir de los movimientos
//  del producto.
//
//  Parámetros
//
//  Salidas
// *****************************************************************************
DefFunc fProcesaSeries(atMovimiento: Tabla; aProceso)
Local lEncabezadoSerie

  // No se ha impreso el encabezado de la serie
  lEncabezadoSerie = 0
  // Busca todos los movimientos de series
  Mientras [ tMovimientoSerie.Busca[@Str(atMovimiento(cIdMovimiento);0)]; tMovimientoSerie->Encontro; tMovimientoSerie.Busca Siguiente[1] ]
    // Busca la serie del movimiento
    tSerie.Busca[@Str(tMovimientoSerie(cIdSerie);0)]
    Si tSerie->Encontro
      // Si no se ha impreso el encabezado de la serie, lo imprime
      Si !lEncabezadoSerie
        // Esta función procesa también pedimentos y lotes cuando el producto tiene también series
        Escoge aProceso
          Caso 1 // Series
            fImprimeEncabezadoSerie()
          FinCaso
          Caso 2 // Lotes
            fImprimeEncabezadoLote()
          FinCaso
          Caso 3 // Pedimentos
            fImprimeEncabezadoPedimento()
          FinCaso
        FinEscoge
        lEncabezadoSerie = 1
      FinSi
      fImprimeSerie(tSerie; aProceso)
    FinSi
  FinMientras
FinFunc


// *****************************************************************************
//  fProcesaCapas
//
//  Esta función lee los movimientos de capas a partir de los movimientos
//  del producto.
//
//  Consideraciones: Verifica si el producto tiene series, además de pedimentos 
//                   o 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
//                    Las combinaciones posibles para pedimentos son:
//                    Pedimentos = 01000 = 8
//                    Pedimentos-Series = 01100 = 12
//                    Pedimentos-Lotes = 11000 = 24
//                    Pedimentos-series-Lotes = 11100 = 28
//
//  Parámetros
//
//  Salidas
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 14/05/2002   CILA    SC 41       Se agrego la implementación de la validación
//                                  de cuando hay capas con caracteristicas y se
//                                  debe excluir documentos de remisiones, dev.
//                                  de remisiones y traspasos. de lo contrario 
//                                  Se maneja en forma normal.
//                                  Se cambio la validación del control de exis-
//                                  tencia descartando el bit de lotes y de pe-
//                                  dimentos. 
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaCapas(atProducto: Tabla; atMovimiento: Tabla; aProceso; aConCaracteristicas)
Local lEncabezadoCapa, lValorModulo 

  lValorModulo = atProducto(cControlExistencia)
  lValorModulo = lValorModulo % 16  // descarto el bit de lotes
  lValorModulo = lValorModulo % 8   // descarto el bit de pedimentos

  // Si el producto tiene series, lo procesa a través de la tabla de series
  Si ((aProceso = 2 O aProceso = 3) Y lValorModulo >= 4) // indica que el bit de series está habilitado, es un 1
    // Procesa las series.
    fProcesaSeries(atMovimiento; aProceso)

  Sino // De otra forma, lo procesa por la tabla de capas
    // No se ha impreso el encabezado de la capa
    lEncabezadoCapa = 0

    // Solo se aplica este filtro cuando hay la combinación de Caracteristicas con Capas.    
    Si aConCaracteristicas = 1
      // Verifica si el documento es una remisión o una devolución de remisiones (clientes)
 		  // En este caso al ser un traspaso entre almacenes, tenemos que discriminar uno de los movimientos ocultos
  	  Si atMovimiento(cIdDocumentoDe) = 3 o atMovimiento(cIdDocumentoDe) = 34 // Si es una remisión o un traspaso
  		  // Discrimina los movimientos de Entrada
   		  Si atMovimiento(cAfectaExistencia) = 1
			  	Retorna
	   	  FinSi
  	  FinSi
	    Si atMovimiento(cIdDocumentoDe) = 6 // Si es una devolución de remisión
  	    // Discrimina los movimientos de Salida
    	  Si atMovimiento(cAfectaExistencia) = 2
	      	Retorna
  	    FinSi
	    FinSi
    FinSi

    // Busca todos los movimientos de capas
    Mientras [ tMovimientoCapa.Busca[@Str(atMovimiento(cIdMovimiento);0)]; tMovimientoCapa->Encontro; tMovimientoCapa.Busca Siguiente[1] ]
      // Busca la capa del movimiento
      tCapa.Busca[@Str(tMovimientoCapa(cIdCapa);0)]
      Si tCapa->Encontro
        // Discrimina capas que no sean de pedimentos o lotes
        Si aProceso = 2 // Lotes?
          Si tCapa(cTipoCapa) != 3 y tCapa(cTipoCapa) != 4
            Continua
          FinSi
        Sino // Pedimentos
          Si tCapa(cTipoCapa) != 2 y tCapa(cTipoCapa) != 4
            Continua
          FinSi
        FinSi
        // Si no se ha impreso el encabezado de la capa, lo imprime
        Si !lEncabezadoCapa
          SI aProceso = 2 // Lotes
            fImprimeEncabezadoLote()
          Sino // Pedimentos
            fImprimeEncabezadoPedimento()
          FinSi
          lEncabezadoCapa = 1
        FinSi
        SI aProceso = 2 // Lotes
          fImprimeLote(tCapa; tMovimientoCapa)
        Sino // Pedimentos
          fImprimePedimento(tCapa; tMovimientoCapa)
        FinSi
      FinSi // tCapa->Encontro
    FinMientras
  FinSi
FinFunc

// *****************************************************************************
//  fProcesaOculto
//
//  Esta función procesa el movimiento oculto, con el fin de diferenciar el 
//  componente con características de un movimiento normal con caracteristicas
//
//  Parámetros
//
//  Salidas
// *****************************************************************************
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 29/05/2002   CILA    ND 527      Se agrego la implementación de la impresión
//                                  de series, pedimentos y lotes cuando se tiene
//                                  caracteristicas y se trata de movimientos 
//                                  generados en un paquete.  
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaOculto(aTipo; atMovimiento: Tabla; atProducto: Tabla; aTextoCaracteristicas)
Local lIdProducto

	Si aTipo = 'N'
	 	// Verifica si el documento es una remisión o una devolución de remisiones (clientes)
 		// En este caso al ser un traspaso entre almacenes, tenemos que discriminar uno de los movimientos ocultos
  	Si atMovimiento(cIdDocumentoDe) = 3 o atMovimiento(cIdDocumentoDe) = 34 // Si es una remisión o un traspaso
  		// Discrimina los movimientos de Entrada
   		Si atMovimiento(cAfectaExistencia) = 1
				Retorna
	   	FinSi
  	FinSi
	  Si atMovimiento(cIdDocumentoDe) = 6 // Si es una devolución de remisión
  	  // Discrimina los movimientos de Salida
    	Si atMovimiento(cAfectaExistencia) = 2
	    	Retorna
  	  FinSi
	  FinSi
	FinSi

	Si aTipo = 'P'  // Componente del paquete con características
		// Busca el registro en el indice primario
		tMovtoOwner.Busca[@Str(atMovimiento(cIdMovimiento);0)]	
		// Muevete un registro hacia arriba
		Si tMovtoOwner->Encontro
	  	Si atMovimiento(cIdDocumentoDe) = 3 o atMovimiento(cIdDocumentoDe) = 34 o atMovimiento(cIdDocumentoDe) = 6
				tMovtoOwner.SaltaReg[-2]
			SiNo
				tMovtoOwner.SaltaReg[-1]
			FinSi
			lIdProducto = tMovtoOwner(cIdProducto)
		FinSi
	SiNo
		lIdProducto = atMovimiento(cIdProducto)
	FinSi

  // Busca el producto del movimiento oculto
  tDetalleProducto.Busca[@Str(lIdProducto;0)]
  Si !tDetalleProducto->Encontro
    Retorna
  FinSi

	// Si el movimiento oculto pertenece a un producto (componente del paquete)
  Si tDetalleProducto(cTipoProducto) = 0
    Retorna
  FinSi

  // Imprime la característica
	Si aTipo = 'P'
		fImprimeCaracteristicas(atProducto; tDetalleProducto; tMovtoOwner; &aTextoCaracteristicas)	

    // El producto puede tener combinacion de Caracteristicas/Series/Pedimentos/Lotes
    Si atProducto(cControlExistencia) = 6 O atProducto(cControlExistencia) = 14 O atProducto(cControlExistencia) = 22 O atProducto(cControlExistencia) = 30

      Si pSeries = 1
        fProcesaSeries(tMovtoOwner; 1) // Series
      FinSi

      Si (atProducto(cControlExistencia) = 22 O atProducto(cControlExistencia) = 30) Y (pLotes = 1)
        fProcesaSeries(tMovtoOwner; 2) // Lotes
      FinSi

      Si (atProducto(cControlExistencia) = 14 O atProducto(cControlExistencia) = 30) Y (pPedimentos = 1)
        fProcesaSeries(tMovtoOwner; 3) // Pedimentos
      FinSi

    // El producto puede tener combinación de Caracteristicas/Pedimentos/Lotes
    Sino
        
      Si (atProducto(cControlExistencia) = 18 O atProducto(cControlExistencia) = 19 O atProducto(cControlExistencia) = 26 O atProducto(cControlExistencia) = 27) Y (pLotes = 1)
        fProcesaCapas(atProducto; tMovtoOwner; 2; 1) // Lotes
      FinSi

      Si (atProducto(cControlExistencia) = 10 O atProducto(cControlExistencia) = 11 O atProducto(cControlExistencia) = 26 O atProducto(cControlExistencia) = 27) Y (pPedimentos = 1) 
        fProcesaCapas(atProducto; tMovtoOwner; 3; 1) // Pedimentos
      FinSi
        
    FinSi
    // FIN S.C.41

	SiNo
	  fImprimeCaracteristicas(atProducto; tDetalleProducto; atMovimiento; &aTextoCaracteristicas)
	FinSi

FinFunc



// *****************************************************************************
//  fProcesaCaracteristicas
//
//  Esta función lee los movimientos de caracteristicas a partir de los 
//  movimientos del producto.
//
//  Consideraciones: Los valores del control de existencias para este ejemplo:
//                    00001 = Unidades de Peso y Medida ( 1)
//                    00010 = Caracteristicas           ( 2)
//                    00100 = Series                    ( 4)
//                    01000 = Pedimentos                ( 8)
//                    10000 = Lotes                     (16)
//                   El cControlExistencias puede tener las siguientes combinaciones
//                   con caracteristicas: 
//                     2 - Caracteristicas
//                     3 - Unidades de Peso y Medida(UPM) + Caracteristicas
//                     6 - Caracteristicas + Series
//                    10 - Caracteristicas + Pedimentos
//                    11 - UPM + Caracteristicas + Pedimentos
//                    14 - Caracteristicas + Series + Pedimentos
//                    18 - Caracteristicas + Lotes
//                    19 - UPM + Caracteristicas + Lotes
//                    22 - Caracteristicas + Series + Lotes
//                    26 - Caracteristicas + Pedimentos + Lotes 
//                    27 - UPM + Caracteristicas + Pedimentos + Lotes
//                    30 - Caracteristicas + Series + Pedimentos + Lotes
//  Parámetros
//
//  Salidas
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 14/05/2002   CILA    SC 41       Se agrego la implementación de la impresión
//                                  de series, pedimentos y lotes cuando se tiene
//                                  caracteristicas.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaCaracteristicas(atProducto: Tabla; atMovimiento: Tabla)
Local lIdMovimiento, lTextoCaracteristicas, 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

  // Inicializa los valores de las banderas de textos
  lTextoCaracteristicas = 0 // No se ha impreso el texto "Características"

  // Si el movimiento que acaba de imprimirse es un movimiento oculto, por ejemplo el movimiento de entrada de una remisión
  Si atMovimiento(cIdMovtoOwner) Y atMovimiento(cMovtoOculto) != 2
    // Entonces busca los detalles de características partiendo del cIdMovtoOwner de dicho movimiento
    lIdMovimiento = atMovimiento(cIdMovtoOwner)
  Sino // Sino, busca los detalles de características de la forma ordinaria
    lIdMovimiento = atMovimiento(cIdMovimiento)
  FinSi
	
	Si atMovimiento(cMovtoOculto) = 2  // Componente del paquete con características
		// Muevete un registro hacia arriba
		fProcesaOculto('P'; atMovimiento; atProducto; &lTextoCaracteristicas)	
	SiNo
	  // Busca los movimientos ocultos del movimiento
		Mientras [ tMovimientoOculto.Busca[@Str(lIdMovimiento;0)]; tMovimientoOculto->Encontro; tMovimientoOculto.Busca Siguiente[1] ]
			fProcesaOculto('N'; tMovimientoOculto; atProducto; &lTextoCaracteristicas)
      // CILA S.C.41

      // El producto puede tener combinacion de Caracteristicas/Series/Pedimentos/Lotes
      Si atProducto(cControlExistencia) = 6 O atProducto(cControlExistencia) = 14 O atProducto(cControlExistencia) = 22 O atProducto(cControlExistencia) = 30

        Si pSeries = 1
          fProcesaSeries(tMovimientoOculto; 1) // Series
        FinSi

        Si (atProducto(cControlExistencia) = 22 O atProducto(cControlExistencia) = 30) Y (pLotes = 1)
          fProcesaSeries(tMovimientoOculto; 2) // Lotes
        FinSi

        Si (atProducto(cControlExistencia) = 14 O atProducto(cControlExistencia) = 30) Y (pPedimentos = 1)
          fProcesaSeries(tMovimientoOculto; 3) // Pedimentos
        FinSi

      // El producto puede tener combinación de Caracteristicas/Pedimentos/Lotes
      Sino
        
        Si (atProducto(cControlExistencia) = 18 O atProducto(cControlExistencia) = 19 O atProducto(cControlExistencia) = 26 O atProducto(cControlExistencia) = 27) Y (pLotes = 1)
          fProcesaCapas(atProducto; tMovimientoOculto; 2; 1) // Lotes
        FinSi

        Si (atProducto(cControlExistencia) = 10 O atProducto(cControlExistencia) = 11 O atProducto(cControlExistencia) = 26 O atProducto(cControlExistencia) = 27) Y (pPedimentos = 1) 
          fProcesaCapas(atProducto; tMovimientoOculto; 3; 1) // Pedimentos
        FinSi
        
      FinSi
      // FIN S.C.41
		FinMientras    
	FinSi
FinFunc



// *****************************************************************************
//  fProcesaMovimientos
//
//  Esta función lee los movimientos del producto ordenados por almacén.
//
//  Parámetros
//
//  Salidas
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/03/2002   CILA    SC 35       Se agrego la validación para mostrar todos 
//                                  los movimientos o solamente los afectados o
//                                  solo los que no estan afectados.
// 07/06/2002		LAP			N.D.659			Se elimino un codigo de debug que no deberia
//																	estar en el reporte final
//  31/10/2002  LAP     N.D.1477    Ubica el documento al que pertenece el
//                                  movimiento a fin de discriminar el concepto.
//                                  En caso de que el producto con series no 
//                                  maneje lotes ni pedimentos no mostrar dicha
//                                  información.
// 14/11/2002   DRdA    N.D.1556    Se abrió el filtro cuando la lista de conceptos
//                                  está vacía que se considera como si se huebieran
//                                  selecionado todos.
//  27/01/2003  LAP     N.D.1377    Los movimientos incompletos de detalles de
//                                  características no se deben de imprimir
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaMovimientos(atProducto: Tabla)
Local lFecha, lCantidad, lCostoCapturado, lCostoMovimiento, lPrecio, lTotal
Local lConceptoIncluido // S.C.224
Local lControlExistencia // N.D.1477
Local lTieneMovtosEnCaptura //N.C.224

  // Inicia N.D.1556
  // S.C.224 Inicio
//!  Si pIdConceptos = 0
//!    Retorna   // 
//!  FinSi
  // S.C.224 Fin
  // Fin N.D.1556
  
  // lee el catálogo de almacenes según el rango especificado en los parámetros
  Mientras [ tAlmacen.Busca[pAlmacenInicial & '..' & pAlmacenFinal]; tAlmacen->Encontro; tAlmacen.Busca Siguiente[1] ]
    // Inicializa variable para impresión de los datos del almacen
    gDatosAlmacen = 0 // No se han impreso los datos del almacen
    // Inicializa variables de totales por almacen
    gAlmTotalCantidad = 0
    gAlmTotalCosto = 0
    // 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) & ':' & tAlmacen(cIdAlmacen) & ':' & lFecha]; tMovimiento->Encontro; tMovimiento.Busca Siguiente[3] ]
// N.D.659 Inicio
//lTemp = atProducto(cIdProducto)
//Imprime lTemp
// N.D.659 Fin
        // Discrimina movimientos sin afectar
        // CILA - SC 35 
        //Si tMovimiento(cAfectadoInventario) = 0      
        //  Continua
        //FinSi

        // N.D.1377 Inicio
        // Discrimina movimientos incompletos de características
        // Revisa si el movimiento corresponde a un detalle de características
        Si tMovimiento(cTipoTraspaso) = 4
          // Busca el producto identificador
          tDetalleProducto.Busca[@Str(tMovimiento(cIdProducto);0)]
          Si tDetalleProducto->Encontro
  	        // Si el producto corresponde a un padre de características, entonces
  	        //  no hay que procesar este movimiento ya que es un movto
  	        //  incompleto de características
            Si tDetalleProducto(cTipoProducto) = 0
              Continua
            FinSi
          FinSi
        FinSi
        // N.D.1377 Fin
        
        // EOD - SC 150 Inicio
        //Si pAfectado = 1 y tMovimiento(cAfectadoInventario) = 0
        //  Continua
        //FinSi
        //Si pAfectado = 2 y tMovimiento(cAfectadoInventario) = 1
        //  Continua
        //FinSi
        // Fin CILA - SC 35 
        
        //N.C.224 Movimientos sin afectar
        //Se deben considerar las unidades que afectaron el inventario 
        //aunque todavía no se afecte el costo, esto sucede cuando todavía se tienen 
        //movimientos en captura.        
        Si tMovimiento(cAfectadoInventario) = 0
          // Si no se han impreso el producto imprimirlo para presentar la advertencia de movtos sin afectar
          Si !gDatosProducto 
            // Imprime los datos del producto
            fImprimeDatosProducto(atProducto)
          FinSi
          Continua
        FinSi
        // EOD - SC 150 Fin
                
        //N.C.224 Debe marcar con una leyenda el movimiento que está siendo capturado en el momento
        //Movimientos solo afectados en existencias
        Si tMovimiento(cAfectadoInventario) = 2
          lTieneMovtosEnCaptura = 1
        Sino
          lTieneMovtosEnCaptura = 0
        FinSi            

        // Discrimina movimientos que no son entradas ni salidas
        Si tMovimiento(cAfectaExistencia) != 1 y tMovimiento(cAfectaExistencia) != 2
          Continua
        FinSi

        // S.C.224 Inicio
        // N.D.1477 Inicio
        // Ubica el documento al que pertenece el 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
        // N.D.1477 Fin

        // Inicia N.D.1556
        Si pIdConceptos != 0
          lConceptoIncluido = False
          lNum = 0
          Mientras (! lConceptoIncluido) Y @Escoge(pIdConceptos;lNum)
           Si @Val(@Escoge(pIdConceptos;lNum)) > 0 Y @Val(@Escoge(pIdConceptos;lNum)) = tDocumento(cIdConceptoDocumento)
             lConceptoIncluido = true  
           FinSi
           lNum = lNum +1
          FinMientras

          Si !lConceptoIncluido
            Continua
          FinSi
        FinSi
        // Fin N.D.1556
        // S.C.224 Fin

        // Obtiene los datos del movimiento
        fObtieneDatosMovimiento(atProducto; tMovimiento; &lCantidad; &lCostoCapturado; &lCostoMovimiento; &lPrecio; &lTotal)
        // Imprime el movimiento        
        fImprimeMovimiento(atProducto; tMovimiento; tAlmacen; lCantidad; lCostoCapturado; lCostoMovimiento; lPrecio; lTotal; lTieneMovtosEnCaptura) //N.C.224
        // Si se imprimen características
        Si pCaracteristicas
          fProcesaCaracteristicas(atProducto; tMovimiento)
        FinSi
        // Si se imprimen series
        Si pSeries
          fProcesaSeries(tMovimiento; 1)
        FinSi
        // N.D.1477 Inicio
        lControlExistencia = atProducto(cControlExistencia)
        Si lControlExistencia >= 32
          lControlExistencia = lControlExistencia - 32
        FinSi
        // Si se imprimen lotes
        Si pLotes y lControlExistencia >= 16
          lControlExistencia = lControlExistencia - 16
          fProcesaCapas(atProducto; tMovimiento; 2; 0)
        FinSi
        // Si se imprimen pedimentos
        Si pPedimentos y lControlExistencia >= 8
          lControlExistencia = lControlExistencia - 8
          fProcesaCapas(atProducto; tMovimiento; 3; 0)
        FinSi
        // N.D.1477 Fin
      FinMientras // tMovimiento->Encontro
      // Incrementa un día a la fecha
      lFecha = fFechaSiguiente(lFecha)
    FinMientras // lFecha <= pFechaFinal
    // Se imprimieron los datos del almacén?
    Si gDatosAlmacen
      // Imprime los totales por almacén
      fImprimeTotales(2; gAlmTotalCantidad; gAlmTotalCosto)
    FinSi
  FinMientras // tAlmacen.Busca
FinFunc

 // **************************************************************************
 //
 //  fVerificaUnidad
 //
 //  Esta función verifica y corrige cualquier inconsistencia del parámetro
 //  del reporte "pUnidad" almacenado en la variable global "lUnidad", en
 //  función del método de costeo del producto y del valor del campo
 //  "cIdUnidadNoConvertible".
 //
 //  Parámetros
 //
 //  Salidas
 //
 //**************************************************************************

 //DefFunc fVerificaUnidad(atProducto: Tabla)
 //Local lUnidad

 //  lUnidad = pUnidad // Se toma lo que diga el parámetro pUnidad

   // Si se solicita el reporte en unidades no convertibles y el producto
   //no tiene unidad no convertible
 //  Si pUnidad = 1 y atProducto(cIdUnidadNoConvertible) = 0
 //    lUnidad = 0 // Se toma la unidad base del producto
 //  FinSi

 //  Retorna lUnidad
 //FinFunc




// *****************************************************************************
//  fVerificaParametros
//
//  Esta función verifica los datos de los parámetros pProducto y pAlmacen, de
//  tal forma que si se tienen los valores PPrimero y PUltimo, se modifican de
//  acuerdo a los códigos del primer y último registro de su respectiva 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

  // Si el rango inicial es el primer almacén, recupera el código del primero
  Si pAlmacenInicial = ' '
    tAlmacen.Busca Primero
    Si tAlmacen->Encontro
      pAlmacenInicial = tAlmacen(cCodigoAlmacen)
    FinSi
  FinSi

  // Si el rango final es el último producto, recupera el código del último
  Si pAlmacenFinal = ' '
    tAlmacen.Busca Ultimo
    Si tAlmacen->Encontro
      pAlmacenFinal = tAlmacen(cCodigoAlmacen)
    FinSi
  FinSi

FinFunc


// *****************************************************************************
// Encabezado del reporte
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 19/03/2002   CILA    SC 35     Se agregaron los textos que incluye los movtos
//                                afectados, sin afectar o todos.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Encab
	Texto '@TC{255,0,0}@S{8}AdminPAQ'
	Hoja '"@TC{0,0,0}@S{8}Hoja: '
	Imprime
  // lee la moneda del reporte
  tMoneda.Busca[@Str(pIdMoneda;0)]
  Si tMoneda->Encontro
    Texto '@TC{0,0,0}@S{8}Moneda: ' & tMoneda(cNombreMoneda)
  FinSi
	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}MOVIMIENTOS DEL INVENTARIO'
	Imprime
	Texto '^@TC{0,0,0}@S{16}Del: ' & fFormateaFecha(pFechaInicial;gIdioma) & ' Al: ' & fFormateaFecha(pFechaFinal;gIdioma)
	Imprime

  // EOD - SC 150 Inicio
  // CILA - SC 35
  //Si pAfectado = 0 // Todos
  // Texto '^@TC{0,0,0}@S{16}Se Incluyen Movimientos Afectados y sin Afectar'
  //FinSi
  //Si pAfectado = 1 // Afectados
  // Texto '^@TC{0,0,0}@S{16}Se Incluyen Movimientos Afectados'
  //FinSi
  //Si pAfectado = 2 // Sin Afectar
  // Texto '^@TC{0,0,0}@S{16}Se Incluyen Movimientos sin Afectar'
  //FinSi
  // Imprime
  // Fin CILA - SC 35
  // EOD - SC 150 Fin

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

  Saltalin

  NEGRITAS TRUE
  // EOD - SC 150 Inicio
  // CILA - SC 35
  // Texto '@TC{0,0,0}@S{10}* - Movimiento que No han sido Afectado en Inventario'
  // Imprime  
  // FIN CILA - SC 35  
  // EOD - SC 150 Fin
  Texto '@TC{0,0,0}@L{-1}'
  Imprime
  Texto C8;'Cliente/'
  Texto C12;'^Costo'
  Texto C14;'^Costo'
  Texto C16;'^Precio'
  Texto C18;'^Total'
  Imprime
  Texto C0;'Fecha'
  Texto C2;'Serie'
  Texto C4;'^Folio'
  Texto C6;'Concepto'
  Texto C8;'Proveedor'
  Texto C10;'^Cantidad'
  Texto C12;'^Capturado'
  Texto C14;'^Movimiento'
  Texto C16;'^de Venta'
  Texto C18;'^(S/impuesto)'
  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()

// Verifica los parámetros pProducto y pAlmacen
fVerificaParametros()

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

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

  // Inicializa variables de totales por producto
  gProdTotalCantidad = 0
  gProdTotalCosto = 0

  // Verifica parámetro pUnidad
  fVerificaUnidad(tProducto)

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

  fProcesaMovimientos(tProducto)

  // Se imprimieron los datos del producto?
  Si gDatosProducto
    // Imprime los totales por producto
    fImprimeTotales(1; gProdTotalCantidad; gProdTotalCosto)
  FinSi

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

FinMientras

Si gAlMenosUno
  fImprimeTotales(3; gTotalCantidad; gTotalCosto)
FinSi

//N.C.224, N.D.5585
Columnas 4;0.10,100,0.0
Lista '(*) Este movimiento está actualmente en captura, por tal motivo solo está afectado en existencia y no en costo'[C1]
