// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
//  CompCostos.rpt
//  Nombre del reporte en el sistema: Comparativo de costos
//
//  Sistema: AdminPAQ v1.1
// 
//  Este reporte perteneciente al módulo de inventarios, despliega el costo
//  histórico y el costo total del producto valuado a costo promedio o 
//  ultimo costo.
//
//	Consideraciones especiales:
//  Este reporte aunque está programado como uno solo, representa en realidad
//  dos reportes en el ámbito del sistema:
//    Comparativo de costos (costo histórico vs costo promedio)
//    Comparativo de costos (costo histórico vs último costo)
//  
//  Elaboró:    Eduardo Pérez Figueroa
//  Fecha: 	    10 de Septiembre del 2001
//
//  Historia de revisiones:
//  Se incluyeron totales por reporte
//  Autor: Gabriela Cuevas 
//  Fecha: 15 de febrero del 2002
//
//  Se incluyo la solicitud de cambio 150 (existencias)
//  Autor: Hector Valencia
//  Fecha: 29 de julio del 2002
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 09/09/2004   LAP     N.D.2922    Corrección para la impresión de la existencia
//                                  del producto
//                                  - fImprimeProducto
// 19/05/2007  JAAM     N.C.147     Esquema de adicion de unidades de compra y venta  
// 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


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

Parametro pFechaCorte = '20021231'      // Fecha de corte o final del reporte
Parametro pProductoInicial = ' '        // Código del producto inicial del rango (' ' = Todos)
Parametro pProductoFinal = ' '          // Código del producto final del rango (' ' = Todos)
Parametro pImprimirProductos = 0        // Productos a imprimir:
                                        // 0 = Todos
                                        // 1 = Solo productos con existencias 
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)
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 = Comparativo de costos (costo histórico vs costo promedio)
                                        // 1 = Comparativo de costos (costo histórico vs último costo)

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

UsaEmpresa tEmpresa;'ADMINPAQW'                   // Parámetros

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

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

UsaTabla tMovimiento = tEmpresa['MGW10010']       // 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
// *** Encabezado del producto
// C0 (Código del producto) = 14 caracteres
// C2 (Nombre del producto) = 53 caracteres
// C10 (Método de costeo) = 29 caracteres
// Columnas 14;2.09,0.15,7.92,0.15,0,0,0,0,0,0,4.33,0.15,0,0
// *** Costos
// C2 (Existencia) = 15 caracteres
// C4 (Unidad de medida o peso) = 3 caracteres
// C6 (Costo total histórico) = 15 caracteres
// C8 (Costo promedio o Ultimo costo) = 15 caracteres
// C10 (Costo total) = 15 caracteres
// C12 (Diferencia) = 15 caracteres
// Columnas 14;2.09,0.15,2.24,0.15,0.45,0.15,2.24,0.15,2.24,0.15,2.24,0.15,2.24,0.15

Columnas 14;2.09,0.15,7.92,0.15,0,0,0,0,0,0,4.33,0.15,0,0
Usaletra 'Arial'
Altura 9
[C2,C6,C8,C10,C12].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
gFechaCorteMasUnDia = 0   // Fecha de corte más un día
gUnidad = pUnidad         // Almacenamiento del parámetro pUnidad
gIdUnidad = pIdUnidad     // Almacenamiento del parametro pIdUnidad  
gMascarillaProducto = ''  // Mascarilla para el código del producto
gTotalReporte = 0.00


// =================================================================================================
// Función área sensible al contexto
// =================================================================================================
DefFunc ContextoDetalleProducto(aNumeroColumna; aValor)
    EJECUTA tEmpresa->SysDirDatos & '\Reportes\AdminPAQ\Kardex.RTW';gFechaIniHistoria,pFechaCorte,@Trim(2;@Escoge(aValor;0)),@Trim(2;@Escoge(aValor;0)),' ',' ',0,0,@Escoge(aValor;2),@Escoge(aValor;3),pIdClase1,pIdClase2,pIdClase3,pIdClase4,pIdClase5,pIdClase6,pIdMoneda,@Escoge(aValor;1);tEmpresa->Directorio
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ó
    [C6,C8,C10,C12].Decimales tParametros(cDecimalesCostos) // Decimales para costos
    [C2].Decimales tParametros(cDecimalesUnidades) // Decimales para existencias
    gMascarillaProducto = tParametros(cMascarillaProducto) // mascarilla para el código del producto
  Sino // Si no encontró el registro de la empresa
    [C2,C6,C8,C10,C12].Decimales 2
  FinSi
FinFunc

// *****************************************************************************
//  fImprimeTotales
//
//	Esta función imprime los totales por producto.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fImprimeTotales(aTotal)
Local vImprime, lSubRaya


  vImprime = ' '[C0..C12]
  vImprime = @Col(aTotal;2)[C2]
  vImprime = @Col(aTotal;6)[C6]
  vImprime = @Col(aTotal;10)[C10]
  vImprime = @Col(aTotal;12)[C12]
  lSubRaya = ''
  lSubRaya = '================='[C2,C6,C10,C12]
  Imprime lSubRaya
  Lista vImprime
  Saltalin
 
FinFunc

// *****************************************************************************
//  fImprimeProducto
//
//	Esta función imprime los datos del producto.
//
//  Parámetros 
//
//  Salidas 
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus                     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 09/09/2004   LAP     N.D.2922    Corrección para la impresión de la existencia
//                                  del producto
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// *****************************************************************************
DefFunc fImprimeProducto(atProducto: Tabla; aExistencia; aCostoHistorico; aCostoUnitario)
Local vImprime, vImprime2, vImprime3, vCostoTotal, vDiferencia, lCodigoEditado, lFechaEditada
Local lFechaSinAfectar, lExistenciaCongelada

  Columnas 14;2.09,0.15,7.92,0.15,0,0,0,0,0,0,4.33,0.15,0,0
  vImprime = ' '[C0..C13]

  // Codigo y nombre del producto
  lCodigoEditado = fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto)
  vImprime = @Col(lCodigoEditado;0)[C0]
  vImprime = atProducto(cNombreProducto)[C2]

  // Método de costeo
  Escoge atProducto(cMetodoCosteo)
    Caso 1
      vImprime = 'Costo Promedio'[C10]
    FinCaso
    Caso 2
      vImprime = 'Costo Promedio por Almacén'[C10]
    FinCaso
    Caso 3
      vImprime = 'Ultimo Costo'[C10]
    FinCaso
    Caso 4
      vImprime = 'UEPS'[C10]
    FinCaso
    Caso 5
      vImprime = 'PEPS'[C10]
    FinCaso
    Caso 6
      vImprime = 'Costo Específico'[C10]
    FinCaso
    Caso 7
      vImprime = 'Costo Estándar'[C10]
    FinCaso
  FinEscoge

  Lista vImprime
  vImprime = ' '[C0..C13]

  // RPC - 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'[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 )
    // Redefine el ancho de las columnas
    // C0 14 caracteres
    // C1 70 caracteres
    Columnas 14; 2.09,0.15,12.40,0
    vImprime = ' '[C0..C13]
    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(cErrorCosto) Y lFechaSinAfectar <= atProducto(cFechaErrorCosto) )
  //    Columnas 17; 2.99,0.15,10.46,0
    Columnas 14; 2.09,0.15,10.46,0
    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

  Columnas 14;2.09,0.15,2.24,0.15,0.45,0.15,2.24,0.15,2.24,0.15,2.24,0.15,2.24,0.15

  // N.D.2922 Inicio
  // Inicialización del renglon
  vImprime = ' '[C0..C13]

  // Corrección a fin de que imprima la existencia
  // Existencia
  vImprime = @Col(aExistencia;0)[C2]

  // 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
  // N.D.2922 Fin

  // Costo histórico
  vImprime = @Col(aCostoHistorico;0)[C6]
  // Costo unitario
  vImprime = @Col(aCostoUnitario;0)[C8]    
  // Costo total
  vCostoTotal = aCostoUnitario * aExistencia
  vImprime = @Col(vCostoTotal;0)[C10]
  // Diferencia
  vDiferencia = aCostoHistorico - vCostoTotal
  vImprime = @Col(vDiferencia;0)[C12]

  DEFREGION ContextoDetalleProducto
  [C2].REGIONINFO atProducto(cCodigoProducto) & ' ,0' & ','& pUnidad & ','& pIdUnidad
  [C6].REGIONINFO atProducto(cCodigoProducto) & ' ,1' & ','& pUnidad & ','& pIdUnidad

  // Imprime los datos
  Lista vImprime

  // Imprime los datos del producto
  gTotalProducto[2]  = @Col(gTotalProducto;2)  + @Col(vImprime;2)
  gTotalProducto[6]  = @Col(gTotalProducto;6)  + @Col(vImprime;6)
  gTotalProducto[10] = @Col(gTotalProducto;10) + @Col(vImprime;10)
  gTotalProducto[12] = @Col(gTotalProducto;12) + @Col(vImprime;12)
FinFunc
 

// *****************************************************************************
//  fProcesaProducto
//
//  Esta función calcula el costo histórico y el costo promedio o último costo
//  del producto.
//
//  Parámetros 
//
//  Salidas 
// *****************************************************************************
DefFunc fProcesaProducto(atProducto: Tabla)
Local lExistencia, lCostoHistorico, lCostoUnitario, lExistenciaBase

  // Existencia del producto
  lExistencia = fExistenciaInicialProducto(atProducto(cIdProducto); 0; gFechaCorteMasUnDia; gIdEjercicio; gPeriodo; pUnidad; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
  // Verifica si imprimir el producto en función de su existencia
  Si !pImprimirProductos o lExistencia != 0.0
    // calcula el costo total historico del producto
    lCostoHistorico = fCostoInicialProducto(atProducto(cIdProducto); 0; gFechaCorteMasUnDia; gIdEjercicio; gPeriodo; atProducto; tMovimiento; tExistencia; tCostoHistorico; tTipoCambio; pIdMoneda)
    // calcula el costo unitario del producto promedio o último costo
    // El cuarto parámetro de la siguiente función es el método de costeo y los valores permitidos son:
    // 1 = Costo promedio
    // 3 = Ultimo costo
    lCostoUnitario = fCostoHistorico(atProducto(cIdProducto); 0; pFechaCorte; pTipoReporte? 3 : 1; tCostoHistorico; tTipoCambio; pIdMoneda)
    // Si el reporte se pidio en unidades no convertibles o equivalentes
    Si pUnidad != 0
      // calcula la existencia en la unidad base
      lExistenciaBase = fExistenciaInicialProducto(atProducto(cIdProducto); 0; gFechaCorteMasUnDia; gIdEjercicio; gPeriodo; 0; atProducto(cIdUnidadBase); pIdUnidad; tMovimiento; tExistencia; tEquivalencia)
      // El costo unitario deberá expresarse en términos de la relación que existe entre la unidad base y la unidad equivalente o no convertible
      lCostoUnitario = lCostoUnitario * lExistenciaBase / lExistencia
    FinSi

    fImprimeProducto(atProducto; lExistencia; lCostoHistorico; lCostoUnitario)
    Saltalin
  FinSi
FinFunc


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

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

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


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

Encab
  Texto '@TC{255,0,0}@S{8}AdminPAQ'
  Hoja '"@TC{0,0,0}@S{8}Hoja: '
  Imprime
  // 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}COMPARATIVO DE COSTOS'
  Imprime
  Si pTipoReporte = 0 // Costo promedio?
  Texto '^@TC{0,0,0}@S{16}COSTO HISTORICO VS COSTO PROMEDIO'
  Sino // Ultimo costo
  Texto '^@TC{0,0,0}@S{16}COSTO HISTORICO VS ULTIMO COSTO'
  Finsi  
  Imprime 
  Texto '^@TC{0,0,0}@S{16}Al: ' & fFormateaFecha(pFechaCorte;gIdioma)
  Imprime

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

  Saltalin

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

  // Redefine el ancho de las columnas
  Columnas 14;2.09,0.15,7.92,0.15,0,0,0,0,0,0,4.33,0.15,0,0

  Texto C0;'Código'
  Texto C2;'Nombre (Producto)'
  Texto C10;'Método de costeo'
  Imprime

  // Redefine el ancho de las columnas
  Columnas 14;2.09,0.15,2.24,0.15,0.45,0.15,2.24,0.15,2.24,0.15,2.24,0.15,2.24,0.15

  Texto C6;'^Costo total'
  Si pTipoReporte = 0 // Costo promedio?
    Texto C8;'^Costo'
  Sino
    Texto C8;'^Ultimo'
  FinSi
  Texto C10;'^Costo total'
  Imprime

  Texto C2;'^Existencia'
  Texto C6;'^Histórico'
  Si pTipoReporte = 0 // Costo promedio?
    Texto C8;'^Promedio'
    Texto C10;'^(Promedio)'
  Sino
    Texto C8;'^Costo'
    Texto C10;'^(Ultimo costo)'
  FinSi
  Texto C12;'^Diferencia'
  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 el rango de productos del reporte
fVerificaParametros()

// A partir de la fecha de corte del reporte, obtiene el ejercicio y periodo correspondiente
// esto es util para el cálculo de la existencia del reporte
// Debido a que se utilizará la función de librería para cálculo de existencia inicial,
// se suma un día a la fecha de corte
gFechaCorteMasUnDia = fFechaSiguiente(pFechaCorte)
fEjercicioPeriodo(gFechaCorteMasUnDia; &gPeriodo; &gIdEjercicio; tEjercicio) 
// Si no se encontró el ejercico, puede ser porque la fecha cae en dos ejercicios futuros,
// Por tanto obtiene el ejercicio y período de la fecha de corte
Si !gIdEjercicio
  fEjercicioPeriodo(pFechaCorte; &gPeriodo; &gIdEjercicio; tEjercicio) 
  // Suma uno al período debido a que se manda llamar funciones de existencia o costo inicial
  gPeriodo = gPeriodo + 1
FinSi

// Obtiene los productos en el rango especificado en los parámetros del reporte
gTotalProducto = 0.00
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 pUnidad = 1 y tProducto(cIdUnidadNoConvertible) = 0
 		Continua
 	Sino
    fVerificaUnidad(tProducto)
  FinSi

  fProcesaProducto(tProducto)

FinMientras

fImprimeTotales(gTotalProducto)
