// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//  RelEntSal.rpt
//  Nombre del reporte en el sistema: Relación de entradas y salidas
//
//  Sistema: AdminPAQ v1.1
// 
//  Este reporte perteneciente al módulo de inventarios, despliega el 
//  inventario inicial, movimientos de entrada y salida, así como el 
//  inventario final de productos tanto en unidades como en importes.
//
//  Consideraciones especiales:
//  Este reporte aunque está programado como uno solo, representa en realidad
//  cuatro reportes en el ámbito del sistema:
//    Relación de entradas y salidas global en unidades
//    Relación de entradas y salidas por almacén en unidades
//    Relación de entradas y salidas global en importes (costo histórico)
//    Relación de entradas y salidas por almacén en importes (costo histórico)
//  
//  Elaboró:    Eduardo Pérez Figueroa
//  Fecha:      07 de Septiembre del 2001
//
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/02/2002   MOFM    SC 23       Se le agregaron más opciones al parámetro
//                                  pImprimirProducto y se agregó pCosto
//                                  Se modificaron los métodos fProcesaGlobal y
//                                  fProcesaPorAlmacen (MOFM)   
// 15/02/2002   MOFM                Se cambia el nombre del reporte de Relacion
//                                  de Entradas y Salidas a Inventario Actual     
// 20/02/2002   CILA    SC 35       Se agrego el parametro para saber si el reporte
//                                  incluye todos los movimientos, o solo los
//                                  movimientos afectados o solo los movimientos
//                                  sin afectar, mostrando en el encabezado del
//                                  reporte información que indica lo anterior.
// 30/04/2002   EGV     N.D.364     Se modificaron las funciones:
//                                  fProcesaGlobal y fProcesaPorAlmacen.
// 21/06/2002   LAP     ND 585      Adición de fExistenciaProductoSinAfectar y
//                                  fCostoProductoSinAfectar para obtener las
//                                  unidades y costo de los movimientos sin
//                                  afectar. Y dependiendo de si el usuario  
//                                  desea ver todos los movimientos, los 
//                                  movimientos afectados o los movimientos sin
//                                  afectar, poder desplegar correctamente la
//                                  existencia o el costo inicial.
//                                  - Cuerpo del reporte
//                                  - fProcesaPorAlmacen
// NOTA: Temporalmente se definen las funciones fExistenciaProductoSinAfectar y
//       fCostoProductoSinAfectar y no en LibInventarios.Rpt ya que algunos
//       reportes no se pueden compilar por que se excede el límite máximo de
//       instrucciones del reporteador.
// 26/07/2002   RPC     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 ND 585 y la SC 35
// 26/07/2002   RPC     ND 955      Cuando se ejecuta el reporte con rangos de 
//                                  fechas que terminana el mismo día pero 
//                                  inician en días diferentes se producen 
//                                  diferencias en el costo final debido a que 
//                                  el cálculo del costo inicial se hace con un
//                                  día de más 
// 23/02/2006   HVA     N.D.3868    Se duplican los costos cuando el producto tiene unidadades no convertibles.
// 21/05/2007   JAAM    N.C.147     Esquema de adicion de unidades de compra y venta 
//  05/02/2008  JENL    N.D.5062    ERROR TARDA 6 MINUTOS AL MOMENTO DE CONVERTIR UN PEDIDO EN FACTURA 
//                                  Se modifica:
//                                  -fProcesaPorAlmacen
//  12/11/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. 
//	01/07/2009  MAJU		N.D.4538		ERROR SE MUESTRAN CANTIDADES INCORRECTAS A PARTIR DE UN PRODUCTO QUE NO TIENE 
//  																LA MISMA UNIDAD NO EQUIVALENTE  QUE EL RESTO CUANDO SE PIDE EL REPORTE POR 
//																	UNIDAD NO EQUIVALENTE  AL GENERAR EL REPORTE INVENTARIO ACTUAL DEL ALMACEN 
//																	POR PRODUCTO (EXCEL) Se modifica: Cuerpo del reporte.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

Incluye LibAdminPAQ.Rpt
Incluye LibInventarios.Rpt


//! *****************************************************************************
//! Nombre:      fExistenciaProductoSinAfectar
//! Descripcion: Calcula la existencia no afectada de un producto antes de una 
//!              fecha
//!
//! Entradas:
//! Salidas:   
//! Consideraciones:
//!    Requiere que la tabla de movimientos use el índice iProductoDoctoDeAfecFecha
//!
//! Historia de Revisiones
//!
//! 21/06/2002    LAP    N.D.585     Implementación inicial
//! 16/07/2002    LAP    N.D.884     Al calcular el inventario inicial se deben
//!                                  de considerar exclusivamente los movimientos 
//!                                  del primer periodo hasta antes de la fecha
//!                                  indicada ya que los movimientos a partir de 
//!                                  la fecha inicial ya se consideran parte del
//!                                  reporte.
//! 26/07/20002    RPC    S.C. 150   Borrar esta función porque ya no se 
//!                                  imprimien movimientos sin afectar
//! *****************************************************************************
//!DEFFUNC fExistenciaProductoSinAfectar(acIdProducto; acIdAlmacen; aFecha; aUnidad; aIdUnidadBase; aIdUnidadEquivalente; atParametros: Tabla; atDocumento: Tabla; atMovimiento: Tabla; atMovtoOwner: Tabla; atEquivalencia: Tabla)
//!LOCAL lUnidad
//!LOCAL lFecha
//!LOCAL lListaDoctoDe, lDoctoModelo, lIdDocumento, lLlave
//!LOCAL lUnidadesMovto, lExistenciaSinAfectar
//!
//!  atMovimiento.Usaindice['iProductoDoctoDeAfecFecha']
//!
//!  lExistenciaSinAfectar = 0
//!
//!  SI aUnidad = 2
//!    lUnidad = aUnidad
//!    aUnidad = 0 // asume unidades base
//!  FINSI
//!
//!  lListaDoctoDe = ' 4, 5, 6, 7,18,19,20,21,32,33,34'[C0]
//!  lFecha = atParametros(cFechaCierre) 
//!  lFecha = fFechaSiguiente(lFecha)
//!  // N.D.884 lFecha <= aFecha
//!  MIENTRAS lFecha < aFecha
//!    lDoctoModelo = 0
//!    MIENTRAS lDoctoModelo < 11
//!      lLlave = acIdProducto &':'&  @Escoge(lListaDoctoDe;lDoctoModelo) &':'& '0' &':'& lFecha
//!      MIENTRAS [atMovimiento.Busca[@Str(lLlave;0)]; atMovimiento->Encontro; atMovimiento.Busca Siguiente[4]]
//!        // Discrimina movimientos cuyo almacén no corresponde al solicitado
//!        SI acIdAlmacen != 0 y atMovimiento(cIdAlmacen) != acIdAlmacen
//!          CONTINUA
//!        FINSI
//!        // Discrimina los movimientos de documentos cancelados
//!        SI atMovimiento(cIdDocumento)
//!          atDocumento.Busca[@Str(atMovimiento(cIdDocumento);0)]
//!        SINO // es un movimiento oculto
//!          // Busca el ID del documento en el movimiento owner
//!          lIdDocumento = fIdDocumentoMovtoOwner(atMovimiento; atMovtoOwner) 
//!          atDocumento.Busca[@Str(lIdDocumento;0)]
//!        FINSI
//!        SI !atDocumento->Encontro
//!          CONTINUA  // Si no se encontró el docto se asume como cancelado   
//!        FINSI
//!        SI atDocumento->Encontro Y atDocumento(cCancelado) = 1   
//!          CONTINUA   // El docto esta cancelado
//!        FINSI
//!        // Recuperar las unidades del movimiento
//!        lUnidadesMovto = fUnidades(aUnidad; aIdUnidadBase; aIdUnidadEquivalente; atMovimiento; atEquivalencia)
//!        SI atMovimiento(cAfectaExistencia) = 1 // es una entrada?
//!          lExistenciaSinAfectar = lExistenciaSinAfectar + lUnidadesMovto
//!        SINO // es una salida
//!          lExistenciaSinAfectar = lExistenciaSinAfectar - lUnidadesMovto
//!        FINSI
//!      FINMIENTRAS  // Hay movimientos sin afectar del documento modelo
//!      lDoctoModelo = lDoctoModelo + 1
//!    FINMIENTRAS  // Hay documentos modelo que afectan existencias
//!    lFecha = fFechaSiguiente(lFecha)
//!  FINMIENTRAS  // Hay días que recorrer
//!
//!  SI lUnidad = 2 // Se solicitó el reporte en unidades equivalentes?
//!    lExistenciaSinAfectar = fUnidadesEquivalentes(lExistenciaSinAfectar; aIdUnidadBase; aIdUnidadEquivalente; atEquivalencia)
//!  FINSI
//!
//!  RETORNA lExistenciaSinAfectar
//!FINFUNC

//! *****************************************************************************
//! Nombre:       fCostoProductoSinAfectar
//! Descripcion:  Calcula un aproximado del costo de los movimientos no afectados 
//!               de un producto antes de una fecha
//!
//! Entradas:
//! Salidas:   
//! Consideraciones:
//!    Requiere que la tabla de movimientos use el índice iProductoDoctoDeAfecFecha
//!
//! Historia de Revisiones
//!
//! 21/06/2002    LAP    N.D.585     Implementación inicial
//! 16/07/2002    LAP    N.D.884     Al calcular el inventario inicial se deben
//!                                  de considerar exclusivamente los movimientos 
//!                                  del primer periodo hasta antes de la fecha
//!                                  indicada ya que los movimientos a partir de 
//!                                  la fecha inicial ya se consideran parte del
//!                                  reporte.
//! 26/07/20002    RPC    S.C. 150   Borrar esta función porque ya no se 
//!                                  imprimien movimientos sin afectar
//! *****************************************************************************
//!DEFFUNC fCostoProductoSinAfectar(acIdProducto; acIdAlmacen; aFecha; aIdMoneda; atParametros: Tabla; atDocumento: Tabla; atMovimiento: Tabla; atMovtoOwner: Tabla; atCostoHistorico: Tabla; atTipoCambio: Tabla)
//!LOCAL  lIndiceAnterior
//!LOCAL lUnidad
//!!LOCAL lFecha
//!LOCAL lListaDoctoDe, lDoctoModelo, lIdDocumento
//!LOCAL lNetoMovto, lGastosMovto
//!LOCAL lNetoDocto, lGastosDocto
//!LOCAL lCostoMovto, lCostoSinAfectar
//!
//!  // Respalda el indice anterior
//!  lIndiceAnterior = atMovimiento->Indice
//!
//!  atMovimiento.Usaindice['iProductoDoctoDeAfecFecha']
//!
//!  lCostoSinAfectar = 0
//!
//!  // Formar una lista con los documentos modelo que afectan existencias
//!  lListaDoctoDe = ' 4, 5, 6, 7,18,19,20,21,32,33,34'[C0]
//!  lFecha = atParametros(cFechaCierre)
//!  lFecha = fFechaSiguiente(lFecha)
//!  // N.D.884 lFecha <= aFecha
//!  MIENTRAS lFecha < aFecha
//!    lDoctoModelo = 0
//!    MIENTRAS lDoctoModelo < 11
//!      lLlave = acIdProducto &':'& @Escoge(lListaDoctoDe;lDoctoModelo) &':'& '0' &':'& lFecha
//!      MIENTRAS [atMovimiento.Busca[@Str(lLlave;0)]; atMovimiento->Encontro; atMovimiento.Busca Siguiente[4]]
//!        // Discrimina movimientos cuyo almacén no corresponde al solicitado
//!        SI acIdAlmacen != 0 y atMovimiento(cIdAlmacen) != acIdAlmacen
//!          CONTINUA
//!        FINSI
//!        // Discrimina los movimientos de documentos cancelados
//!        SI atMovimiento(cIdDocumento)
//!          atDocumento.Busca[@Str(atMovimiento(cIdDocumento);0)]
//!        SINO // es un movimiento oculto
//!          // Busca el ID del documento en el movimiento owner
//!          lIdDocumento = fIdDocumentoMovtoOwner(atMovimiento; atMovtoOwner) 
//!          atDocumento.Busca[@Str(lIdDocumento;0)]
//!        FINSI
//!        SI !atDocumento->Encontro
//!          CONTINUA  // Si no se encontró el docto se asume como cancelado   
//!        FINSI
//!        SI atDocumento->Encontro Y atDocumento(cCancelado) = 1   
//!          CONTINUA  // El docto esta cancelado
//!        FINSI
//!        SI atMovimiento(cAfectaExistencia) = 1 // es una entrada?
//!          // Calcula el neto del movimiento
//!          lNetoMovto   = atMovimiento(cNeto) - atMovimiento(cDescuento1) - atMovimiento(cDescuento2) - atMovimiento(cDescuento3) - atMovimiento(cDescuento4) - atMovimiento(cDescuento5) 
//!          // Calcular el gasto del movimiento, a través de un aregla de tres con respecto al
//!          // neto y gastos del documento
//!          lGastosDocto = atDocumento(cGasto1) + atDocumento(cGasto2) + atDocumento(cGasto3)
//!          lNetoDocto   = atDocumento(cNeto) - atDocumento(cDescuentoMov) 
//!          lGastosMovto = lNetoMovto * lGastosDocto / lNetoDocto 
//!          // Calcula el costo del movimiento incluyendo gastos sobre compra
//!          lNetoMovto   = lNetoMovto * atDocumento(cTipoCambio)  // Neto en moneda base
//!          lCostoMovto  = lNetoMovto + lGastosMovto
//!          // Convierte el costo a la moneda del reporte
//!          lCostoMovto  = fConvierteTipoCambio(lCostoMovto; 1; aIdMoneda; aFecha; atTipoCambio)
//!          lCostoSinAfectar = lCostoSinAfectar + lCostoMovto
//!        SINO  // Es un salida
//!          // Tomar como costo del movimiento el costo promedio
//!          lCostoMovto = fCostoHistorico(acIdProducto; acIdAlmacen; aFecha; 1; atCostoHistorico; atTipoCambio; aIdMoneda)
//!          lCostoMovto = lCostoMovto * atMovimiento(cUnidades)
//!          lCostoSinAfectar = lCostoSinAfectar - lCostoMovto
//!        FINSI
//!      FINMIENTRAS  // Hay movimientos sin afectar del documento modelo
//!      lDoctoModelo = lDoctoModelo + 1
//!    FINMIENTRAS  // Hay documentos modelo que afectan existencias
//!    lFecha = fFechaSiguiente(lFecha)
//!  FINMIENTRAS  // Hay días que recorrer 
//!
//!  // Restaura el indice original
//!  atMovimiento.Usaindice[lIndiceAnterior]
//!
//!  RETORNA lCostoSinAfectar
//!FINFUNC


// *****************************************************************************
//  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)
Parametro pImprimirProductos = 0        // Productos a imprimir:
                                        // 0 = Todos
                                        // 1 = Sólo productos con movimientos 
                                        // 2 = Sólo con existencias  
                                        // 3 = Con Movimientos o existencias
// RPC - SC 150 Ahora siempre se imprimen sólo los movimientos afectados y si
// hay no afectados se consideran error
//!Parametro pAfectado = 0                 // Movimientos a imprimir
//!                                        // 0 = Todos
//!                                        // 1 = Afectados
//!                                        // 2 = Sin Afectar  
// FIN RPC - SC 150
Parametro pCosto = 0                    // Método de Costeo:
                                        // 0 = Definido por el producto
                                        // 1 = Costo Promedio (Global)
                                        // 2 = Costo Promedio (Por Almacén)
                                        // 3 = Ultimo Costo (Global)
                                        // 4 = Ultimo Costo (Por Almacén)
                                             
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               
Parametro pIdMoneda = 1                 // Id de la moneda a expresar el reporte
Parametro pTipoReporte = 0              // Tipo de Reporte (este parámetro es interno a AdminPAQ)
                                        // 0 = Relación de entradas y salidas global en unidades
                                        // 1 = Relación de entradas y salidas por almacén en unidades
                                        // 2 = Relación de entradas y salidas global en importes (costo histórico)
                                        // 3 = Relación de entradas y salidas por almacén en importes (costo histórico)

// *****************************************************************************
//  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 tAlmacen = tEmpresa['MGW10003']          // Almacenes
tAlmacen.Usaindice['cCodigoAlmacen']              // cCodigoAlmacen

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

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

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 tEjercicio = tEmpresa['MGW10031']        // Ejercicios
tEjercicio.Usaindice['cNumeroEjercicio']          // cNumeroEjercicio

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

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 tTipoCambio = tEmpresa['MGW10035']       // Tipo de cambio
tTipoCambio.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 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 (Código del producto o almacén) = 14 caracteres
// C2 (Nombre del producto o almacén) = 36 (global en unidades) o 29 (global en importes) o 40 caracteres (por almacén)
// C4 (Unidad de medida o peso) = 3 caracteres (global en unidades) o 10 caracteres (global en importes)
// C6 (Inventario inicial) = 14 caracteres
// C8 (Entradas) = 14 caracteres
// C10 (Salidas) = 14 caracteres
// C12 (Existencia o Costo total) = 14 caracteres
// C14 (Rotación inventario) = 10 caracteres
// C16 RPC - SC 150: Indica el número de error del producto si tiene
Si pTipoReporte = 0 // global en unidades
    //N.C.224
    Columnas 18;2.09,0.15,5.38,0.15,0.45,0.15,2.09,0.15,2.09,0.15,2.09,0.15,2.09,0.15,1.49,0.15,0.75,0.75
Sino
  Si pTipoReporte = 2 // global en importes
    //N.C.224   
    Columnas 18;2.09,0.15,4.33,0.15,1.49,0.15,2.09,0.15,2.09,0.15,2.09,0.15,2.09,0.15,1.49,0.15,0.75,0.75
  Sino // por almacén
    Columnas 18;2.09,0.15,6.58,0.00,0.00,0.15,2.09,0.15,2.09,0.15,2.09,0.15,2.09,0.15,1.49,0.15,0.75,0.75
  FInSi
FinSi

Usaletra 'Arial'
Altura 9
[C6,C8,C10,C12,C14].Coma


// *****************************************************************************
//  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
gPeriodo = 0              // Numero de período que corresponde a la fecha de corte del reporte
gIdEjercicio = 0          // ID del ejercicio que contiene la fecha de corte del reporte
gUnidad = pUnidad         // Almacenamiento del parámetro pUnidad
gIdUnidad = pIdUnidad     // Almacenamiento del parámetro pIdUnidad
gMascarillaProducto = ''  // Mascarilla para el código del producto
gMascarillaAlmacen = ''   // Mascarilla para el código del almacén
gTotalInventario = 0.00
gTotalEntradas = 0.00
gTotalSalidas = 0.00
// RPC - SC 150 Ahora se maneja un número que indica si el producto tiene error
//!gAsterisco = ''           // Manejo visual de productos con movimientos sin afectar. 
gTieneMovtosEnCaptura = 0    //N.C.224

// Función área sensible al contexto
// =================================================================================================
DefFunc ContextoDetalleProducto(aNumeroColumna; aValor)
Local lTipoKardex
Local lAlmacenInicio
Local lAlmacenFin
  
  lTipoKardex = pTipoReporte
  // pTipoReporte   0 = Relación de entradas y salidas global en unidades
  //                1 = Relación de entradas y salidas por almacén en unidades
  //                2 = Relación de entradas y salidas global en importes (costo histórico)
  //                3 = Relación de entradas y salidas por almacén en importes (costo histórico)
  // pTipoKardex    0 = Kardex en unidades
  //                1 = Kardex en importes
  //                2 = Kardex en unidades por almacén
  //                3 = Kardex en importes por almacén  
  Si pTipoReporte = 1
    lTipoKardex = 2
  FinSi
  Si pTipoReporte = 2
    lTipoKardex = 1
  FinSi

  lAlmacenInicio = pAlmacenInicial
  lAlmacenFin = pAlmacenFinal
  Si @Escoge(aValor;1) != ''
    lAlmacenInicio = @Escoge(aValor;1)
    lAlmacenFin = lAlmacenInicio
  FinSi
    EJECUTA tEmpresa->SysDirDatos & '\Reportes\AdminPAQ\Kardex.RTW';pFechaInicial,pFechaFinal,@Trim(2;@Escoge(aValor;0)),@Trim(2;@Escoge(aValor;0)),lAlmacenInicio,lAlmacenFin,0,0,pUnidad,pIdUnidad,pIdClase1,pIdClase2,pIdClase3,pIdClase4,pIdClase5,pIdClase6,pIdMoneda,lTipoKardex;tEmpresa->Directorio
FinFunc

// *****************************************************************************
// fCancelado  :  Verifca si el movto es de un docto cancelado, 
// salidas 1 = cancelado, 0 = no cancelado
// *****************************************************************************
Deffunc fCancelado(atMovimiento:Tabla)
  local lvalorregreso,lIdDocumento

  // 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
  lvalorregreso = 1 // cancelado en caso de no encontrar el docto.
  Si tDocumento->Encontro
    lvalorregreso =  tDocumento(cCancelado)    // Regresa el estado del campo
  Finsi

  Retorna lvalorregreso

FinFunc

// *****************************************************************************
//  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ó
    Si pTipoReporte = 0 o pTipoReporte = 1 // Reporte en unidades?
      [C6,C8,C10,C12].Decimales tParametros(cDecimalesUnidades) // Decimales para existencias
    Sino // Reporte en costos
      [C6,C8,C10,C12].Decimales tParametros(cDecimalesCostos) // Decimales para costos
    FinSi
    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
    [C6,C8,C10,C12].Decimales 2
  FinSi
  // Razón de rotación de inventarios
  [C14].Decimales 2
FinFunc


// *****************************************************************************
//  fImprimeAlmacen
//
//  Esta función imprime los datos del almacén para el reporte por almacén.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/02/2002   CILA    SC 35       Se agrego al código del almacen la concate-
//                                  nación del asterisco, cuando el producto tiene
//                                  movimientos sin afectar.
// 26/07/2002   RPC     SC 150      Se quito el asterísco que indicaba movtos 
//                                  sin afectar porque el error ahora se indica 
//                                  junto con los datos del producto
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fImprimeAlmacen(atProducto:Tabla; atAlmacen: Tabla; aInvInicial; aEntradas; aSalidas)
Local vImprime, lInvFinal, lRotacion, lPromedio, lCodigoEditado

  vImprime = ' '[C0..C15]

  // Codigo y nombre del almacén
  lCodigoEditado = fMascarilla(atAlmacen(cCodigoAlmacen); gMascarillaAlmacen)
// RPC - SC 150 Ahora se maneja un número que indica si el producto tiene error
//!  // CILA - SC 35
//!  lCodigoEditado = gAsterisco & lCodigoEditado
//!  // Fin CILA - SC 35 
// FIN // RPC - SC 150
  vImprime = @Col(lCodigoEditado;0)[C0]
  vImprime = atAlmacen(cNombreAlmacen)[C2]
    
  vImprime = @Col(aInvInicial;0)[C6]
  vImprime = @Col(aEntradas;0)[C8]
  vImprime = @Col(aSalidas;0)[C10]
  //DEFREGION ContextoDetalleProducto
  Si aEntradas != 0
    [C8].REGIONINFO atProducto(cCodigoProducto) & ' ,' & atAlmacen(cCodigoAlmacen)
  FinSi
  Si aSalidas != 0
    [C10].REGIONINFO atProducto(cCodigoProducto) & ' ,' & atAlmacen(cCodigoAlmacen)
  FinSi
  // calcula el inventario final
  lInvFinal = aInvInicial + aEntradas - aSalidas
  vImprime = @Col(lInvFinal;0)[C12]
  // calcula la rotación de inventarios
  // Rotacion = Salidas / ((InvInicial + InvFinal) / 2)
  lPromedio = (aInvInicial + lInvFinal) / 2
  Si lPromedio != 0
    lRotacion = aSalidas / lPromedio
  Sino
    lRotacion = 0.0
  FinSi
  vImprime = @Col(lRotacion;0)[C14]

  //N.C.224
  vImprime = ' '[C17] //Limpia la variable
  //Se activó la bandera si detecta que hubo algún movimiento con cAfectadoInventario = 2
  Si gTieneMovtosEnCaptura = 1 
		vImprime = '(*)'[C17]  				
  FinSi
  	
  Lista vImprime
FinFunc


// *****************************************************************************
//  fImprimeDatosProducto
//
//  Esta función imprime los datos del producto para el reporte por Almacén.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 26/07/2002   RPC     SC 150      Se agrearon mensajes de error de existencias 
//                                  negativas, costos y movtos sin afectar
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fImprimeDatosProducto(atProducto: Tabla)
Local vImprime, vImprime2, vImprime3, lCodigoEditado
Local lFechaSinAfectar, lExistenciaCongelada

  // Redefine la configuración de las columnas
  // C0 14 caracteres
  // C2 75 caracteres
  Columnas 17;2.09,0.15,11.21,0.15

  vImprime = ' '[C0..C15]

  NEGRITAS TRUE

  vImprime = 'Producto: '[C0]
  lCodigoEditado = fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto)
// RPC - SC 150 Ahora se maneja un mensaje de error del producto
//!  // CILA - SC 35
//!  lCodigoEditado = gAsterisco & lCodigoEditado
//!  // Fin CILA - SC 35 
// FIN RPC - SC 150
  vImprime = @Col(lCodigoEditado;0)[C2]
  Lista vImprime
  
  vImprime = 'Nombre: '[C0]
  vImprime = atProducto(cNombreProducto)[C2]
  Lista vImprime
  
  Si pTipoReporte = 0 o pTipoReporte = 1 // Reporte en unidades?
    // 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)[C2]
        Lista vImprime
      FinSi
    FinSi

  // Reporte en importes
  Sino 
    vImprime = 'Costeo: '[C0]
    Escoge atProducto(cMetodoCosteo)
      Caso 1
        vImprime = 'Costo Promedio'[C2]
      FinCaso
      Caso 2
        vImprime = 'Costo Promedio por Almacén'[C2]
      FinCaso
      Caso 3
        vImprime = 'Ultimo Costo'[C2]
      FinCaso
      Caso 4
        vImprime = 'UEPS'[C2]
      FinCaso
      Caso 5
        vImprime = 'PEPS'[C2]
      FinCaso
      Caso 6
        vImprime = 'Costo Específico'[C2]
      FinCaso
      Caso 7
        vImprime = 'Costo Estándar'[C2]
      FinCaso
    FinEscoge
    Lista vImprime    
  FinSi  // Si es reporte en unidades o en importes

  // RPC - SC 150 Verificar si el producto tiene algún error y sí es así 
  // desplegar en la última columna el número de 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'[C2]
    vImprime2 = '*** Se recomienda aplicar el inventario físico'[C2]
    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'[C2]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C2]
        vImprime3 = ''
      FinCaso
      Caso 2
        vImprime =  '*** Captura en desorden de salidas'[C2]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C2]
        vImprime3 = ''
      FinCaso
      Caso 3
        vImprime =  '*** Existencias negativas'[C2]
        vImprime2 = '*** Se recomienda registrar las entradas necesarias'[C2]
        vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C2]
      FinCaso
      Caso 4
        vImprime =  '*** Series sin movimiento de entrada'[C2]
        vImprime2 = '*** Se recomienda registrar la entrada de las series pendientes'[C2]
        vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C2]
      FinCaso
      Caso 5
        vImprime =  '*** Series sin costo'[C2]
        vImprime2 = '*** Se recomienda ejecutar el proceso "Recosteo" para éste producto'[C2]
        vImprime3 = ''
      FinCaso
    FinEscoge
    lFechaEditada = fFormateaFecha(atProducto(cFechaErrorCosto); gIdioma)
    vImprime = @Col(vImprime;2) & ' a partir del ' & @Col(lFechaEditada;0)[C2]
    Lista vImprime
    Lista vImprime2
    Si vImprime3 
      Lista vImprime3
    FinSi
  FinSi  // Si hay error de costos

  // 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(cFechaErrorCosto) Y lFechaSinAfectar <= atProducto(cFechaErrorCosto) )
    vImprime = 'Error en costos:'[C0]
    vImprime = '*** Movimientos sin afectar'[C2]
    lFechaEditada = fFormateaFecha(lFechaSinAfectar; gIdioma)
    vImprime = @Col(vImprime;2) & ' a partir del ' & @Col(lFechaEditada;0)[C2]
    vImprime2 = '*** Se recomienda consultar el reporte "Movimientos sin Afectar"'[C2]
    vImprime3 = '*** y ejecutar el proceso "Recosteo" para éste producto'[C2]
    Lista vImprime
    Lista vImprime2
    Lista vImprime3
  FinSi  // Hay error de movimientos sin afectar
  // FIN RPC - SC 150

  SaltaLin	

  NEGRITAS FALSE

  // Regresa las columnas a su configuracion original
  //N.C.224
  Columnas 18;2.09,0.15,5.38,0.15,0.45,0.15,2.09,0.15,2.09,0.15,2.09,0.15,2.09,0.15,1.49,0.15,0.75,0.75
  

FinFunc


// *****************************************************************************
//  fImprimeProducto
//
//  Esta función imprime los datos del producto para el reporte global.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/02/2002   CILA    SC 35       Se agrego al código del producto la concate-
//                                  nación del asterisco, cuando el producto tiene
//                                  movimientos sin afectar.
// 26/07/2002   RPC     SC 150      Se quito el asterísco y se sustituyó por una
//                                  columna con el número de error
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fImprimeProducto(atProducto: Tabla; aInvInicial; aEntradas; aSalidas)
Local vImprime, lInvFinal, lRotacion, lPromedio, lCodigoEditado, lFechaSinAfectar
Local lExistenciaCongelada

  vImprime = ' '[C0..C16]

  // Codigo y nombre del producto
  lCodigoEditado = fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto)
// RPC - SC 150 No imprimir el asterísco, en su lugar usar un número que indica
// si el producto tiene error y cual es 
//!  // CILA - SC 35 
//!  lCodigoEditado = gAsterisco & lCodigoEditado 
//!  // Fin CILA - SC 35
// FIN RPC - SC 150
  vImprime = @Col(lCodigoEditado;0)[C0]
  vImprime = atProducto(cNombreProducto)[C2]
    
  Si pTipoReporte = 0 o pTipoReporte = 1 // Reporte en unidades?
    // 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
      vImprime = tUnidad(cDespliegue)[C4]
    FinSi
  Sino // Reporte en importes
    Escoge atProducto(cMetodoCosteo)
      Caso 1
        vImprime = 'Prom.'[C4]
      FinCaso
      Caso 2
        vImprime = 'Prom. Alm.'[C4]
      FinCaso
      Caso 3
        vImprime = 'U. Costo'[C4]
      FinCaso
      Caso 4
        vImprime = 'UEPS'[C4]
      FinCaso
      Caso 5
        vImprime = 'PEPS'[C4]
      FinCaso
      Caso 6
        vImprime = 'Específico'[C4]
      FinCaso
      Caso 7
        vImprime = 'Estándar'[C4]
      FinCaso
    FinEscoge
  FinSi

  vImprime = @Col(aInvInicial;0)[C6]
  vImprime = @Col(aEntradas;0)[C8]
  vImprime = @Col(aSalidas;0)[C10]
  // calcula el inventario final
  lInvFinal = aInvInicial + aEntradas - aSalidas
  vImprime = @Col(lInvFinal;0)[C12]
  // calcula la rotación de inventarios
  // Rotacion = Salidas / ((InvInicial + InvFinal) / 2)
  lPromedio = (aInvInicial + lInvFinal) / 2
  Si lPromedio != 0
    lRotacion = aSalidas / lPromedio
  Sino
    lRotacion = 0.0
  FinSi
  vImprime = @Col(lRotacion;0)[C14]

  //DEFREGION ContextoDetalleProducto
  Si aEntradas != 0
    [C8].REGIONINFO atProducto(cCodigoProducto)
  FinSi
  Si aSalidas != 0
    [C10].REGIONINFO atProducto(cCodigoProducto)
  FinSi

  // RPC - SC 150 Verificar si el producto tiene algún error y sí es así 
  // desplegar en la última columna el número de error
   vImprime = ''[C16]

  // 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 = '(7)'[C16]
    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 = '('  & atProducto(cErrorCosto) & ')'[C16]
  FinSi // Si hay error de costos
  
  // 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 = '(6)'[C16]
  FinSi
  // FIN RPC - SC 150
  
  //N.C.224
  vImprime = ' '[C17] //Limpia la variable
  //Se activó la bandera si detecta que hubo algún movimiento con cAfectadoInventario = 2
  Si gTieneMovtosEnCaptura = 1 
  	Si pTipoReporte = 0 o pTipoReporte = 2  // global en unidades
  		vImprime = '(8)'[C17]
  	SiNo  		
  		vImprime = '(*)'[C17]  		
  	FinSi 	
  FinSi
  
  Lista vImprime
FinFunc


// *****************************************************************************
//  fImprimeTotales
//
//  Esta función imprime los totales por producto.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotales(aInvInicial; aEntradas; aSalidas; aGranTotal)
Local vImprime, lInvFinal, lRotacion, lPromedio

  Si !aGranTotal
    Texto C6;'@L{6}'
    Texto C8;'@L{8}'
    Texto C10;'@L{10}'
    Texto C12;'@L{12}'
  // Texto C14;'@L{14}'
    Imprime
  SiNo
    lSubRaya = ''
    lSubRaya = '================='[C6,C8,C10,C12]
    Imprime lSubRaya
  FinSi
  
  vImprime = ' '[C0..C15]
  Si !aGranTotal
    vImprime = '^Total producto:'[C2]
  FinSi

  vImprime = @Col(aInvInicial;0)[C6]
  vImprime = @Col(aEntradas;0)[C8]
  vImprime = @Col(aSalidas;0)[C10]
  // calcula el inventario final
  lInvFinal = aInvInicial + aEntradas - aSalidas
  vImprime = @Col(lInvFinal;0)[C12]
  // calcula la rotación de inventarios
  // Rotacion = Salidas / ((InvInicial + InvFinal) / 2)
  lPromedio = (aInvInicial + lInvFinal) / 2
  Si lPromedio != 0
    lRotacion = aSalidas / lPromedio
  Sino
    lRotacion = 0.0
  FinSi
  vImprime = @Col(lRotacion;0)[C14]

  Lista vImprime

  Saltalin
FinFunc


// *****************************************************************************
//  fProcesaGlobal
//
//  Esta función procesa el reporte de stock máximo global.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/02/2002   MOFM    SC 23       Se le agregaron las validaciones para le manejo
//                                  de las nuevas opciones de pImprimirProducto 
//                                  y del parámetro pCosto (MOFM)   
// 20/03/2002   CILA    SC 35       Se modifica para mostrar todos los movimientos 
//                                  solo los movimientos afectado o solo los 
//                                  movimientos sin afectar.
//                                  Se agrego la inicialización de la variable global
//                                  gAsterisco para imprimir en el producto que
//                                  tiene movimientos pendientes de afectar.
// 30/04/2002   EGV     ND 364      Se imprime el asterisco '*' sí y solo sí el
//                                  movimiento no está afectado y el Documento
//                                  padre no está cancelado.
// 21/06/2002   LA      ND 585      Adición de fExistenciaProductoSinAfectar y
//                                  fCostoProductoSinAfectar para obtener las
//                                  unidades y costo de los movimientos sin
//                                  afectar. Y dependiendo de si el usuario  
//                                  desea ver todos los movimientos, los 
//                                  movimientos afectados o los movimientos sin
//                                  afectar, poder desplegar correctamente la
//                                  existencia o el costo inicial.
// 26/07/20002  RPC     SC 150      Ya no se calcula la existencia y costo sin 
//                                  afectar y no se imprimen movtos sin afectar
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaGlobal(atProducto: Tabla)
Local lFecha, lInvInicial, lEntradas, lSalidas, lCostoExistencia
Local lCosto, lTotal, lIdAlmacen
// RPC - SC 150 Ya no se necesitan estas variables
//!// N.D.585 Inicio
//!LOCAL lInvInicialAfectado, lInvInicialSinAfectar
//!LOCAL lImporteInicialAfectado, lImporteInicialSinAfectar
//!// N.D.585 Fin
// FIN RPC - SC 150

//N.C.224
gTieneMovtosEnCaptura = 0

  // Inicia acumulados
  lEntradas = 0.0
  lSalidas = 0.0
  lTotal = 0.0 

  // RPC - ND 955 El cálculo del costo inicial se hacía con un día de más 
  // provocando que el costo inicial fuera incorrecto. Por ejemplo, se calculaba
  // el costo al 01-01-02  y luego se buscaban los movimientos del mismo día
  Si pTipoReporte = 0 // Reporte global en unidades?
//!    lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
    lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
  Sino                 // Reporte global en importes
    // Si el costo es por producto y su método es Estándar se calcula en base a las unidades y el valor del costo estándar en el producto
    Si atProducto(cMetodoCosteo) = 7
      lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
      lInvInicial = lInvInicial * atProducto(cCostoEstandar)
    SiNo
      lInvInicial = fCostoInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; atProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
    FinSi
  FinSi
  // FIN RPC - ND 955
// RPC - SC 150 Ya no se incluyen existencias o costos sin afectar
//!  // N.D.585 Inicio
//!  // Obtiene el inventario inicial del producto en todos los almacenes
//!  Si pTipoReporte = 0 // Reporte global en unidades?
//!    //!lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
//!    lInvInicialAfectado   = 0
//!    lInvInicialSinAfectar = 0
//!    SI pAfectado = 0 O pAfectado = 1  // Movimientos afectados y/o todos
//!      lInvInicialAfectado = fExistenciaInicialProducto(tProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
//!    FINSI
//!    SI pAfectado = 0 O pAfectado = 2  // Movimientos sin afectar y/o todos
//!      lInvInicialSinAfectar = fExistenciaProductoSinAfectar(tProducto(cIdProducto); 0; pFechaInicial; pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tParametros; tDocumento; tMovimiento; tMovtoOwner; tEquivalencia)
//!    FINSI
//!    lInvInicial = lInvInicialAfectado + lInvInicialSinAfectar[C0]
//!  Sino                 // Reporte global en importes
//!    //!lInvInicial = fCostoInicialProducto(atProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; atProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
//!    lImporteInicialAfectado   = 0
//!    lImporteInicialSinAfectar = 0
//!    SI pAfectado = 0 O pAfectado = 1  // Movimientos afectados y/o todos
//!      lImporteInicialAfectado = fCostoInicialProducto(tProducto(cIdProducto); 0; pFechaInicial; gIdEjercicio; gPeriodo; tProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
//!    FINSI
//!    SI pAfectado = 0 O pAfectado = 2  // Movimientos sin afectar y/o todos
//!      lImporteInicialSinAfectar = fCostoProductoSinAfectar(tProducto(cIdProducto); 0; pFechaInicial; pIdMoneda; tParametros; tDocumento; tMovimiento; tMovtoOwner; tCostoHistorico; tTipoCambio)
//!    FINSI
//!    lInvInicial = lImporteInicialAfectado + lImporteInicialSinAfectar[C0]
//!  FinSi
//!  // N.D.585 Fin
//FIN RPC - SC 150

  // 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] ]
// RPC SC 150 Ya no se imprimen movtos sin afectar
//!      // Discrimina movimientos sin afectar
//!      // CILA - SC 35
//!      //Si tMovimiento(cAfectadoInventario) = 0
//!      //  Continua
//!      //FinSi
//!      Si pAfectado = 1 y tMovimiento(cAfectadoInventario) = 0
//!        Continua
//!      FinSi
//!      Si pAfectado = 2 y tMovimiento(cAfectadoInventario) = 1
//!        Continua
//!      FinSi
//!      // Fin CILA - SC 35
// FIN RCP SC 150
      // Discrimina los movimientos que no son entradas ni salidas
      Si tMovimiento(cAfectaExistencia) != 1 y tMovimiento(cAfectaExistencia) != 2
        Continua
      FinSi
      // FBCS descarta los movtos de doctos cancelados
      Si fCancelado(tMovimiento)
        Continua
      Finsi

      // Se verifica si está o no afectado en inventarios después de verificar
      // que el Documeto del movimiento no esté cancelado.
      //N.C.224
      //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
// RPC - SC 150 Ahora se maneja un número de error del producto y no se imrpimen
// movtos sin afectar
//!        gAsterisco = '*'
        Continua
        // FIN RPC - SC 150
      FinSi
      
      //N.C.224
      //Si detecta que hubo algún movimiento con cAfectadoInventario = 2, se activa la bandera 
      Si tMovimiento(cAfectadoInventario) = 2
       gTieneMovtosEnCaptura = 1       
      FinSi      

      Si pTipoReporte = 0 // Reporte global en unidades?
        lCostoExistencia = fUnidades(pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tEquivalencia)
      Sino // Reporte global en importes
        lIdAlmacen = 0
        Si pCosto = 2 o pCosto = 4  // Costo Promedio por almacén o último costo
          lIdAlmacen = tMovimiento(cIdAlmacen)
        FinSi
        Si pCosto = 0 
          lCostoExistencia = fCostoMovimiento(atProducto; tMovimiento; tCostoHistorico; tTipoCambio; pIdMoneda)
        Sino
          Si pCosto = 1 o pCosto = 2 // Costo promedio
            lCosto = fCostoHistorico(atProducto(cIdProducto);lIdAlmacen;lFecha;1;tCostoHistorico;tTipoCambio;pIdMoneda)
          Sino // Ultimo costo
            lCosto = fCostoHistorico(atProducto(cIdProducto);lIdAlmacen;lFecha;3;tCostoHistorico;tTipoCambio;pIdMoneda)
          FinSi
            lCostoExistencia = lCosto * tMovimiento(cUnidades)
        FinSi     
      FinSi
      Si tMovimiento(cAfectaExistencia) = 1 // Es una entrada?
        lEntradas = lEntradas + lCostoExistencia
      Sino
        lSalidas = lSalidas + lCostoExistencia
      FinSi
    FinMientras
    // Incrementa un día a la fecha
    lFecha = fFechaSiguiente(lFecha)
  FinMientras

  // Imprime el producto
  lTotal = lInvInicial + lEntradas - lSalidas 
  // Todos los productos o los que tengan al menos un movimiento
  Si (pImprimirProductos = 0) o (AlMenosUno) o (pImprimirProductos = 1 y ((lSalidas != 0) o (lEntradas!=0)))
    fImprimeProducto(atProducto; lInvInicial; lEntradas; lSalidas)
    gTotalInventario = gTotalInventario + lInvInicial
    gTotalEntradas   = gTotalEntradas   + lEntradas
    gTotalSalidas    = gTotalSalidas    + lSalidas
  FinSi 
  Si (pImprimirProductos = 2 Y lTotal != 0) o (pImprimirProductos = 3 y (((lSalidas!=0) o (lEntradas != 0)) o lTotal != 0))
    fImprimeProducto(atProducto; lInvInicial; lEntradas; lSalidas)
    gTotalInventario = gTotalInventario + lInvInicial
    gTotalEntradas   = gTotalEntradas   + lEntradas
    gTotalSalidas    = gTotalSalidas    + lSalidas
  FinSi 

FinFunc


// *****************************************************************************
//  fProcesaPorAlmacen
//
//  Esta función procesa el reporte de stock máximo por almacén.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 15/02/2002   MOFM    SC 23       Se le agregaron las validaciones para le manejo
//                                  de las nuevas opciones de pImprimirProducto 
//                                  y del parámetro pCosto (MOFM)   
// 20/03/2002   CILA    SC 35       Se modifica para mostrar todos los movimientos 
//                                  solo los movimientos afectado o solo los 
//                                  movimientos sin afectar.   
//                                  Se agrego la inicialización de la variable global
//                                  gAsterisco para imprimir en el producto que
//                                  tiene movimientos pendientes de afectar.
// 30/04/2002   EGV     N.D.364     Se imprime el asterisco '*' sí y solo sí el
//                                  movimiento no está afectado y el Documento
// 21/06/2002   LA      ND 585      Adición de fExistenciaProductoSinAfectar y
//                                  fCostoProductoSinAfectar para obtener las
//                                  unidades y costo de los movimientos sin
//                                  afectar. Y dependiendo de si el usuario  
//                                  desea ver todos los movimientos, los 
//                                  movimientos afectados o los movimientos sin
//                                  afectar, poder desplegar correctamente la
//                                  existencia o el costo inicial.
// 26/07/20002  RPC     SC 150      Ya no se calcula la existencia y costo sin 
//                                  afectar y no se imprimen movtos sin afectar
//05/02/2008    JENL    N.D.5062    Se cambia el indice iProductoAlmacenFechaAfec por iProductoAlmacenAfecFecha (JENL).
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DefFunc fProcesaPorAlmacen(atProducto: Tabla)
Local lFecha, lInvInicial, lEntradas, lSalidas, lCostoExistencia
Local lTotalInvInicial, lTotalEntradas, lTotalSalidas
Local lDatosProducto, lImpreso
Local lCosto, lTota, lIdAlmacen
// RPC - SC 150 Ya no se necesitan estas variables
//!// N.D.585 Inicio
//!// N.D.585 Inicio
//!LOCAL lInvInicialAfectado, lInvInicialSinAfectar
//!LOCAL lImporteInicialAfectado, lImporteInicialSinAfectar
//!// N.D.585 Fin
// FIN RPC - SC 150
//N.C.224
gTieneMovtosEnCaptura = 0 //Inicializa la variable

  // Imprimir todos los productos
  Si !pImprimirProductos
    // Imprime los datos del producto
    fImprimeDatosProducto(atProducto)
    lDatosProducto = 1
  Sino
    lDatosProducto = 0
  FinSi

  // Inicia acumulados por producto
  lTotalInvInicial = 0.0
  lTotalEntradas = 0.0
  lTotalSalidas = 0.0
  lImpreso = 0 

  // Recorre los almacenes en el rango
  Mientras [ tAlmacen.Busca[pAlmacenInicial & '..' & pAlmacenFinal]; tAlmacen->Encontro; tAlmacen.Busca Siguiente[1] ]    
    // Inicia acumulados por almacen
    lEntradas = 0.0
    lSalidas = 0.0
    // Encuentra el inventario inicial del producto en ese almacén
    // Establece el indice necesario para la rutina de inventario inicial
    tMovimiento.Usaindice['iProductoFechaAfecta'] // cIdProducto+cFecha+cAfectaExistencia

  // RPC - ND 955 El cálculo del costo inicial se hacía con un día de más 
  // provocando que el costo inicial fuera incorrecto. Por ejemplo, se calculaba
  // el costo al 01-01-02  y luego se buscaban los movimientos del mismo día
    Si pTipoReporte = 1 // Reporte por almacén en unidades?
//!      lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
      lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
    Sino // Reporte por almacén en importes
      // Si el costo es por producto y su método es Estándar se calcula en base a las unidades y el valor del costo estándar en el producto
      Si atProducto(cMetodoCosteo) = 7
        lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
        lInvInicial = lInvInicial * atProducto(cCostoEstandar)
      SiNo
        lInvInicial = fCostoInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; atProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
      FinSi
    Finsi
    // RPC - ND 955
// RPC - SC 150 Ya no se incluyen existencias o costos sin afectar
//!    // N.D.585 Inicio
//!    Si pTipoReporte = 1 // Reporte por almacén en unidades?
//!      //!lInvInicial = fExistenciaInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
//!      lInvInicialAfectado   = 0
//!      lInvInicialSinAfectar = 0
//!      SI pAfectado = 0 O pAfectado = 1  // Movimientos afectados y/o todos
//!        lInvInicialAfectado = fExistenciaInicialProducto(tProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
//!      FINSI
//!      SI pAfectado = 0 O pAfectado = 2  // Movimientos sin afectar y/o todos
//!        lInvInicialSinAfectar = fExistenciaProductoSinAfectar(tProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tParametros; tDocumento; tMovimiento; tMovtoOwner; tEquivalencia)
//!      FINSI
//!      lInvInicial = lInvInicialAfectado + lInvInicialSinAfectar[C0]
//!    Sino // Reporte por almacén en importes
//!      //!lInvInicial = fCostoInicialProducto(atProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; atProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
//!      lImporteInicialAfectado   = 0
//!      lImporteInicialSinAfectar = 0
//!      SI pAfectado = 0 O pAfectado = 1  // Movimientos afectados y/o todos
//!        lImporteInicialAfectado = fCostoInicialProducto(tProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; gIdEjercicio; gPeriodo; tProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
//!      FINSI
//!      SI pAfectado = 0 O pAfectado = 2  // Movimientos sin afectar y/o todos
//!        lImporteInicialSinAfectar = fCostoProductoSinAfectar(tProducto(cIdProducto); tAlmacen(cIdAlmacen); pFechaInicial; pIdMoneda; tParametros; tDocumento; tMovimiento; tMovtoOwner; tCostoHistorico; tTipoCambio)
//!      FINSI
//!      lInvInicial = lImporteInicialAfectado + lImporteInicialSinAfectar[C0]
//!    FinSi
//!    // N.D.585 Fin
// FIN RPC - SC 150
    // Establece el indice de recorrido
    tMovimiento.Usaindice['iProductoAlmacenFechaAfec'] // cIdProducto+cIdAlmacen+cFecha+cAfectaExistencia
    //N.C.224tMovimiento.Usaindice['iProductoAlmacenAfecFecha'] // cIdProducto+cIdAlmacen+CAFECTADOINVENTARIO+cFecha N.D.5062
    // 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] ]    	            
// RPC SC 150 Ya no se imprimen movtos sin afectar
//!        // Discrimina movimientos sin afectar
//!        // CILA - SC 35 
//!        //Si tMovimiento(cAfectadoInventario) = 0      
//!        //  Continua
//!        //FinSi
//!        Si pAfectado = 1 y tMovimiento(cAfectadoInventario) = 0
//!          Continua
//!        FinSi
//!        Si pAfectado = 2 y tMovimiento(cAfectadoInventario) = 1
//!          Continua
//!        FinSi 
//!        // Fin CILA - SC 35
// FIN RPC - SC 150
        // Discrimina los movimientos que no son entradas ni salidas
        Si tMovimiento(cAfectaExistencia) != 1 y tMovimiento(cAfectaExistencia) != 2
          Continua
        FinSi

        // FBCS descarta los movtos de doctos cancelados
        Si fCancelado(tMovimiento)
         Continua
        Finsi

        // Se verifica si está o no afectado en inventarios después de verificar
        // que el Documeto del movimiento no esté cancelado.
        //N.D.5062 Inicio
        //Si tMovimiento(cAfectadoInventario) != 1
// RPC - SC 150 Ahora se maneja un número de error del producto y no se imrpimen
// movtos sin afectar
//!          gAsterisco = '*'
          //Continua
          // FIN RPC - SC 150
        //FinSi
        //N.D.5062 Fin
        
        //N.C.224
  	    //Si detecta que hubo algún movimiento con cAfectadoInventario = 2, se activa la bandera    	  
    	  Si tMovimiento(cAfectadoInventario) = 2 
      	 gTieneMovtosEnCaptura = 1      	 
      	FinSi            

        Si pTipoReporte = 1 // Reporte por almacén en unidades?
          lCostoExistencia = fUnidades(pUnidad; tProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tEquivalencia)
        Sino // Reporte global en importes
          lIdAlmacen = 0
          Si pCosto = 2 o pCosto = 4  // Costo Promedio por almacén o último costo
            lIdAlmacen = tMovimiento(cIdAlmacen)
          FinSi
          Si pCosto = 0 
            lCostoExistencia = fCostoMovimiento(atProducto; tMovimiento; tCostoHistorico; tTipoCambio; pIdMoneda)
          Sino
            Si pCosto = 1 o pCosto = 2 // Costo promedio
              lCosto = fCostoHistorico(atProducto(cIdProducto);lIdAlmacen;lFecha;1;tCostoHistorico;tTipoCambio;pIdMoneda)
            Sino // Ultimo costo
              lCosto = fCostoHistorico(atProducto(cIdProducto);lIdAlmacen;lFecha;3;tCostoHistorico;tTipoCambio;pIdMoneda)
            FinSi
              lCostoExistencia = lCosto * tMovimiento(cUnidades)
          FinSi     
        FinSi

        Si tMovimiento(cAfectaExistencia) = 1 // Es una entrada?
          lEntradas = lEntradas + lCostoExistencia
        Sino
          lSalidas = lSalidas + lCostoExistencia
        FinSi       
        
      FinMientras // tMovimiento->Encontro
      // Incrementa un día a la fecha
      lFecha = fFechaSiguiente(lFecha)
    FinMientras // lFecha <= pFechaFinal

    // Imprime el almacén

    // Imprime el producto
    lTotal = lInvInicial + lEntradas - lSalidas 

    // Todos los productos o los que tengan al menos un movimiento
    Si (pImprimirProductos = 0) o (AlMenosUno) o (pImprimirProductos = 1 y ((lSalidas != 0) o (lEntradas!=0)))
      // Si no se han impreso los datos del producto, se imprimen
      Si !lDatosProducto
        fImprimeDatosProducto(atProducto)
        lDatosProducto = 1
      FinSi
      fImprimeAlmacen(atProducto; tAlmacen; lInvInicial; lEntradas; lSalidas)
      gTieneMovtosEnCaptura = 0 //Inicializa la variable
      lImpreso = 1
    FinSi 

    Si (pImprimirProductos = 2 Y lTotal != 0) o (pImprimirProductos = 3 y (((lSalidas!=0) o (lEntradas != 0)) o lTotal != 0))
      // Si no se han impreso los datos del producto, se imprimen
      Si !lDatosProducto
        fImprimeDatosProducto(atProducto)
        lDatosProducto = 1
      FinSi
      fImprimeAlmacen(atProducto; tAlmacen; lInvInicial; lEntradas; lSalidas)
      lImpreso = 1
    FinSi 
    // acumula al total del producto
    Si lImpreso = 1
      lTotalInvInicial = lTotalInvInicial + lInvInicial
      lTotalEntradas = lTotalEntradas + lEntradas
      lTotalSalidas = lTotalSalidas + lSalidas
      lImpreso = 0
    FinSi
  FinMientras // tAlmacen.Busca
  // Imprime el total del producto
  Si lDatosProducto
    fImprimeTotales(lTotalInvInicial; lTotalEntradas; lTotalSalidas; 0)
    gTotalInventario = gTotalInventario + lTotalInvInicial
    gTotalEntradas   = gTotalEntradas   + lTotalEntradas
    gTotalSalidas    = gTotalSalidas    + lTotalSalidas
  FinSi

FinFunc


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

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

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

  Si pTipoReporte = 1 o pTipoReporte = 3 // Si el reporte es por almacén
    // 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)
        // Si el almacén inicial es el almacén cero, lee el siguiente
        Si !tAlmacen(cCodigoAlmacen)
          tAlmacen.Saltareg[1]
          Si tAlmacen->Encontro
            pAlmacenInicial = tAlmacen(cCodigoAlmacen)
          FinSi
        FinSI
      FinSi
    FinSi  

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

 
// *****************************************************************************
// Encabezado del reporte

// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 20/03/2002   CILA    SC 35     Se agregaron los textos que incluye los movtos
//                                afectados, sin afectar o todos.
//                                Ademas se mostrar una leyenda de describe el 
//                                significado del asterisco.
// 26/07/20002  RPC     SC 150    Ya no se imprime el texto de inclusión de 
//                                movimientos sin afectar
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Encab
  Texto '@TC{255,0,0}@S{8}AdminPAQ'
  Hoja '"@TC{0,0,0}@S{8}Hoja: '
  Imprime
  Si pTipoReporte = 2 o pTipoReporte = 3 // Reporte en importes?
    // lee la moneda del reporte
    tMoneda.Busca[@Str(pIdMoneda;0)]
    Si tMoneda->Encontro
      Texto '@TC{0,0,0}@S{8}Moneda: ' & tMoneda(cNombreMoneda)
    FinSi
  FinSi
  Texto '"@TC{0,0,0}@S{8}Fecha: ' & fFormateaFecha(@Hoy();gIdioma)
  Imprime

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

  Si pTipoReporte = 0 o pTipoReporte = 2 // Global?
    Texto '^@TC{0,0,0}@S{16}INVENTARIO ACTUAL GLOBAL'
  Sino // Por Almacén
    Texto '^@TC{0,0,0}@S{16}INVENTARIO ACTUAL POR ALMACEN'
  Finsi  
  Imprime
  Si pTipoReporte = 0 o pTipoReporte = 1 // En unidades?
    Texto '^@TC{0,0,0}@S{16}EN UNIDADES'
  Sino // En importes
    Si pCosto = 0
      Texto '^@TC{0,0,0}@S{16}EN IMPORTES (COSTO DEFINIDO POR EL PRODUCTO)'
    FinSi
    Si pCosto = 1
      Texto '^@TC{0,0,0}@S{16}EN IMPORTES (COSTO PROMEDIO GLOBAL)'
    FinSi
    Si pCosto = 2
      Texto '^@TC{0,0,0}@S{16}EN IMPORTES (COSTO PROMEDIO POR ALMACEN)'
    FinSi
    Si pCosto = 3
      Texto '^@TC{0,0,0}@S{16}EN IMPORTES (ULTIMO COSTO GLOBAL)'
    FinSi
    Si pCosto = 4
      Texto '^@TC{0,0,0}@S{16}EN IMPORTES (ULTIMO COSTO POR ALMACEN)'
    FinSi
  Finsi  
  Imprime
  Texto '^@TC{0,0,0}@S{16}Del: ' & fFormateaFecha(pFechaInicial;gIdioma) & ' Al: ' & fFormateaFecha(pFechaFinal;gIdioma)
  Imprime

// RPC - SC 150 Como ya no se incluyen movtos sin afectar ( sólo se detectan y
// se despliega un error ) este mensaje es innecesario
//!  // 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
// FIN RPC - SC 150

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

  Saltalin

  NEGRITAS TRUE
// RPC - SC 150 Como ya no se usa el asterísco para indicar errores del producto
// este mensaje ya no es necesario
//!  // CILA - SC 35
//!  Texto '@TC{0,0,0}@S{10}* - Existen movimientos que No han sido Afectados en Inventario, Se recomienda ejecutar el proceso "Recosteo" para estos productos'
//!  Imprime  
//!  // FIN CILA - SC 35  
// FIN RPC - SC 150
  Texto '@TC{0,0,0}@L{-1}'
  Imprime
  Si pTipoReporte = 2 // Global en importes?
    Texto C4;'Método'
  FinSi
  Texto C6;'^Inventario'
  Texto C14;'^Rotación'
  Imprime

  Texto C0;'Código'
  Si pTipoReporte = 0 o pTipoReporte = 2 // Global?
    Texto C2;'Nombre (Producto)'
  Sino // Por Almacén
    Texto C2;'Nombre (Almacén)'
  Finsi  
  Si pTipoReporte = 2 // Global en importes?
    Texto C4;'Costeo'
  FinSi
  Texto C6;'^Inicial'
  Texto C8;'^Entradas'
  Texto C10;'^Salidas'
  Si pTipoReporte = 0 o pTipoReporte = 1 // En unidades?
    Texto C12;'^Existencia'
  Sino // En importes
    Texto C12;'^Costo Total'
  FinSi
  Texto C14;'^Inventario'
  // RPC - SC 150 En los reportes globales se usa una columna extra 
  // para mostrar si hay error de existencias o costos
  Si pTipoReporte = 0 o pTipoReporte = 2 // Reporte global?
    Texto C16;'Error'
  FinSi
  // FIN RPC - SC 150
  Imprime
  Texto '@TC{0,0,0}@L{-1}'
  Imprime 1
  NEGRITAS FALSE

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


// *****************************************************************************
// Cuerpo del reporte
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

// Configura los decimales del reporte
fConfiguraDecimales()

// Verifica el rango de productos del reporte
fVerificaParametros()

fEjercicioPeriodo(pFechaInicial; &gPeriodo; &gIdEjercicio; tEjercicio) 

gTotalInventario = 0.0
gTotalEntradas   = 0.0
gTotalSalidas    = 0.0

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

  // Verifica parámetro pUnidad
  //N.D.4538 (MAJU)
  //Al elegir como filtro “Unidad no equivalente” Si uno de los productos a mostrar 
  //no tiene asignada Unidad No Equivalente no se mostrara en el reporte.
  Si pTipoReporte = 0 o pTipoReporte = 1 // Reporte en unidades?
		Si pUnidad = 1 y tProducto(cIdUnidadNoConvertible) = 0
 			Continua
 		Sino
 			fVerificaUnidad(tProducto)
  	FinSi
  FinSi

  DEFREGION ContextoDetalleProducto
  Si pTipoReporte = 0 o pTipoReporte = 2 // Reporte global?
    fProcesaGlobal(tProducto)
  Sino // por almacén
    fProcesaPorAlmacen(tProducto)
  FinSi

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

FinMientras

fImprimeTotales(gTotalInventario; gTotalEntradas; gTotalSalidas; 1)

// RPC - SC 150 En los reportes globales ahora se imprime al final la leyenda 
// con los errores de existencias o costos
Si pTipoReporte = 0 o pTipoReporte = 2 // Reporte global?
Columnas 17;0.14,19.0,0.0
  Saltalin
  Lista '', 'Errores de existencias o costos:'[C1]
  Lista '', ' (1) Captura en desorden de entradas'[C1]
  Lista '', ' (2) Captura en desorden de salidas'[C1]
  Lista '', ' (3) Existencias negativas'[C1]
  Lista '', ' (4) Series sin movimiento de entrada'[C1]
  Lista '', ' (5) Series sin costo'[C1]  
  Lista '', ' (6) Movimientos sin afectar'[C1]
  Lista '', ' (7) En proceso de levantamiento de inventario físico'[C1]
  //N.C.224
  Lista '', ' (8) Este producto está incluido en algún movimiento que actualmente está en captura, motivo por el cual dicho movimiento solo está afectado en existencia y no en costo'[C1]
  Saltalin
  Lista '', 'En caso de captura en desorden de entradas se recomienda ejecutar el proceso "Recosteo" para los productos con errores'[C1]
  Lista '', 'En caso de captura en desorden de salidas se recomienda ejecutar el proceso "Recosteo" para los productos con errores'[C1]
  Lista '', 'En caso de existencias Negativas se recomienda registrar las entradas necesarias y ejecutar el proceso "Recosteo" para los productos con errores'[C1]
  Lista '', 'En caso de series sin movimiento de entrada la existencia puede no coincidir con las series desplegadas, se recomienda registrar la entrada de las series pendientes'[C1]
  Lista '', 'En caso de series sin costo se recomienda ejecutar el proceso "Recosteo" para los productos con errores'[C1]
  Lista '', 'En caso de movimientos sin afectar se recomienda consultar el reporte "Movimientos sin Afectar"'[C1]
  Lista '', 'En caso de inventario físico se recomienda aplicar el inventario físico'[C1]
  //N.C.224
  Lista '', 'En este caso se recomienda consultar el reporte en cuanto se termine de capturar el documento'[C1]  
SiNo
	Columnas 17;0.14,19.0,0.0	
	//N.C.224
	Lista '', ' (*) Este producto está incluido en algún movimiento que actualmente está en captura, motivo por el cual dicho movimiento solo está afectado en existencia y no en costo'[C1]  
Finsi
// FIN RPC - SC 150

