// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//	Nombre del reporte en el sistema: Movimientos del Almacén por Concepto
//
//	Consideraciones especiales:
//  
//	Elaboró:    Leonardo Aguilar Pizano
//	Fecha: 	    24 de Septiembre de 2002
//  Lotus Notes:  S.C.242
//
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Historia de modificaciones
//  Fecha      Nombre   IDLotus     Descripcion
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 05/02/2008  JENL     N.D.5062    Se cambia el indice iProductoAlmacenFechaAfec por iProductoAlmacenAfecFecha (JENL). 
//                                  Se modifico:
//                                  Cuerpo del reporte.
// 05/12/2008 	ELVS   N.C.224      Se deben considerar los movimientos que están con el 
//              MAJU                campo cAfectadoInventario = 2, se agrega marca y leyenda
//                                  de que esos movimientos están en captura.  
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

// *********************************************************************************************************************
// Funciones de librería
// *********************************************************************************************************************
Incluye LibAdminPAQ.Rpt
//Incluye LibInventariosO.Rpt
Incluye LibInventarios.Rpt


// *********************************************************************************************************************
// P A R A M E T R O S
// *********************************************************************************************************************
Parametro pFechaInicial 			= '20020901'  // Fecha inicial del rango
Parametro pFechaFinal 				= '20020930'  // Fecha final del rango
Parametro pAlmacenInicial 		= ' '         // Código del almacén inicial del rango (' ' = Todos)
Parametro pAlmacenFinal 			= ' '         // Código del almacén final del rango (' ' = Todos)
Parametro	pListaConceptos			= '4,5,20,21'		// Lista de conceptos que afectan al invetario
Parametro	pImprimirConceptos	= 1						// 0 - Todos
																						// 1 - Solo con movimientos
Parametro pIdMonedaReporte 		= 1          	// Id de la moneda a expresar el reporte
Parametro pDetallado					= 1						// 0 - Concentrado 
																						// 1 - Detallado


// *********************************************************************************************************************
//	Tablas a utilizar e Indices de búsqueda por omisión
// *********************************************************************************************************************
UsaEmpresa tEmpresa;'ADMINPAQW'                   // Parámetros

UsaTabla tAlmacen = tEmpresa['MGW10003']          // Almacenes
tAlmacen.Usaindice['cCodigoAlmacen']              // cCodigoAlmacen

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

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

// Productos identificadores a fin de saber si el producto es un detalle de caracteristicas o no
UsaTabla tDetalleProducto = tEmpresa['MGW10004']  // Productos
tDetalleProducto.Usaindice['']                    // Indice primario: cIdProducto

UsaTabla tDoctoModelo = tEmpresa['MGW10007']			// Documentos modelos
tDoctoModelo.Usaindice['']

UsaTabla tConceptoDocto = tEmpresa['MGW10006']		// Conceptos de documentos
tConceptoDocto.Usaindice['']

UsaTabla tDocumento = tEmpresa['MGW10008'] Alias 'Doctos'       // Documentos
tDocumento.Usaindice['']                          // Indice primario: cIdDocumento
UsaTabla tDoctoAuxiliar = tEmpresa['MGW10008'] Alias 'DoctosConcepto'       // Documentos
tDoctoAuxiliar.Usaindice['iConceptoFecha']                          // Indice primario: cIdDocumento

UsaTabla tMovimiento = tEmpresa['MGW10010']   Alias 'Movtos'    // Movimientos
tMovimiento.Usaindice['iProductoAlmacenFechaAfec']     

UsaTabla tMovtoOwner = tEmpresa['MGW10010'] 	Alias 'MovtoOwner'  // Movimientos
tMovtoOwner.Usaindice['iMovtoOwnerMovto']

UsaTabla tMovtoSinAfectar = tEmpresa['MGW10010'] Alias 'MovtoSinAfectar'  // Movimientos
tMovtoSinAfectar.Usaindice['']

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

UsaTabla tExistencia = tEmpresa['MGW10030']				// Existencia
tExistencia.Usaindice['iProdEjerAlmacenTipo']

UsaTabla tCostoHistorico = tEmpresa['MGW10017']		// Costo Historico
tCostoHistorico.Usaindice['iProdAlmacenFecha']

UsaTabla tMoneda = tEmpresa['MGW10034']           // Monedas
tMoneda.Usaindice['']

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

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


// *********************************************************************************************************************
// Definiciones y asumidos globales para el reporte
// *********************************************************************************************************************
// Ancho de columnas = caracteres / 17 * 2.54
// Se consideran columnas intermedias de un espacio
Si pDetallado = 0
	// C1 (Codigo) 					= 15 caracteres
	// C3 (Concepto) 				= 35 caracteres
	// C5 (Tipo) 						=  5 caracteres
	// C7 (Unidades) 				= 12 caracteres
	// C9 (Gastos)					= 15 caracteres
	// C11 (Costo total) 		= 15 caracteres
	//N.C.224
	Columnas 16;0.15,2.25,0.25,5.50,0.25,2.00,0.25,1.80,0.25,2.25,0.25,2.25,0.50,1.00,0.50,0.15
	[C7,C9,C11].Coma
	gColLeyenda		= 5
	gColUnidades 	= 7
	gColGastos		=	9
	gColTotal 		= 11
	gColError			= 13
Sino
	// C1 (Fecha) 						= 12 caracteres
	// C3 (Documento modelo) 	= 25 caracteres
	// C5 (Serie) 						=  5 caracteres
	// C7 (Folio) 						= 12 caracteres
	// C9 (Codigo) 						= 10 caracteres
	// C11 (Producto) 				= 25 caracteres
	// C13 (Unidades) 				= 10 caracteres
	// C15 (Gastos)						= 12 caracteres
	// C17 (Costo total) 			= 12 caracteres
	//N.C.224
	//Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.15,0.75,0.50,0.15
	//N.D. 7572
	Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,1.15,0.75,0.50,0.15
	[C13,C15,C17].Coma
	gColLeyenda		= 11
	gColUnidades 	= 13
	gColGastos		=	15
	gColTotal 		= 17
	gColError			= 19
FinSi
Usaletra 'Arial'
Altura 9


// *********************************************************************************************************************
//	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
gMascarillaProducto = ''  // Mascarilla para el código del producto
gMascarillaAlmacen 	= ''   // Mascarilla para el código del almacén

gTotalAlmacen 					= 0.00	// Acumulado del almacen
gAlmacenConMovimientos	= 0			// Bandera para saber si el almacén tiene movimientos
gImpresoAlmacen					= 0			// Bandera para indicar que ya se imprimieron los datos 
																//	del almacen

gTotalConcepto 					= 0.0		// Acumulado del concepto
gConceptoConMovimientos = 0			// Bandera para saber si el concepto tiene movimientos
gImpresoConcepto				= 0			// Bandera para indicar que ya se imprimieron los datos 
																//	del producto

gTotalReporte						= 0.00	// Acumulado del reporte
gReporteConMovimientos 	= 0			// Bandera para saber si el reporte tiene movimientos

gErrorEnCostos	= 0				// Bandera para saber si en el reporte se presentarón errores de
													//	costo
gCodigoError		= ' '			// Codigo de error del movimiento actual

// Obtención de las mascarillas
tParametros.Busca Primero
gMascarillaAlmacen 	= tParametros(cMascarillaAlmacen)
gMascarillaProducto	= tParametros(cMascarillaProducto)

gProductoInicial 	= ' '
gProductoFinal 		= ' '

//N.C.224
gTieneMovtosEnCaptura = 0

// Obtención de la moneda del reporte y de sus decimales
gDecimalesMonedaReporte = 2    // Número de decimales en la moneda
gNombreMonedaReporte 		= 'Peso Mexicano'
tMoneda.Busca[@Str(pIdMonedaReporte;0)]
Si tMoneda->Encontro
	gDecimalesMonedaReporte = tMoneda(cDecimalesMoneda)
	gNombreMonedaReporte 		= tMoneda(cNombreMoneda)
FinSi

Si pListaConceptos = 0
	tConceptoDocto.Busca Primero
	pListaConceptos = ''
	Mientras tConceptoDocto->Encontro
		tDoctoModelo.Busca[@Str(tConceptoDocto(cIdDocumentoDe);0)]
		Si tDoctoModelo->Encontro Y tDoctoModelo(cAfectaExistencia) < 3
			Si pListaConceptos != ''
				pListaConceptos = pListaConceptos & ','
			FinSi
			pListaConceptos = pListaConceptos & tConceptoDocto(cIdConceptoDocumento)
		FinSi
		tConceptoDocto.SaltaReg[1]
	FinMientras
FinSi

// Obtención del número de conceptos a imprimir
gNumeroConceptos = 0
Mientras @Escoge(pListaConceptos; gNumeroConceptos)
  gNumeroConceptos = gNumeroConceptos +1
FinMientras


// *********************************************************************************************************************
// F U N C I O N E S
// *********************************************************************************************************************
// Función área sensible al contexto
// =================================================================================================
DefFunc ContextoDetalleAlmacenCpto(aNumeroColumna; aValor)
    EJECUTA tEmpresa->SysDirDatos & '\Reportes\AdminPAQ\MovAlmConcepto.RTW';pFechaInicial,pFechaFinal,@Escoge(aValor;0),@Escoge(aValor;0),@Escoge(aValor;1),pImprimirConceptos,pIdMonedaReporte,1;tEmpresa->Directorio
FinFunc

// *********************************************************************************************************************
// Descripción:	Configura el número de decimales de las columnas de importes, basado en los parámetros de la empresa.
//  Parámetros 
//  Salidas 
// *********************************************************************************************************************
DefFunc fConfiguraDecimalesyMascaras()

	Si pDetallado = 0
		[C7].Decimales tParametros(cDecimalesUnidades)
  	[C9].Decimales gDecimalesMonedaReporte
  	[C11].Decimales gDecimalesMonedaReporte
	Sino
		[C7].Decimales 0	// Folio
		[C13].Decimales tParametros(cDecimalesUnidades)
  	[C15].Decimales gDecimalesMonedaReporte
  	[C17].Decimales gDecimalesMonedaReporte
	FinSi
FinFunc


// *********************************************************************************************************************
// Descripción:	
//  Parámetros 
//  Salidas 
// *********************************************************************************************************************
DefFunc fVerificaParametros()

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

	tProducto.Busca Primero
	Si tProducto->Encontro
		gProductoInicial = tProducto(cCodigoProducto)
	FinSi
	tProducto.Busca Ultimo
	Si tProducto->Encontro
		gProductoFinal = tProducto(cCodigoProducto)
	FinSi
FinFunc


// *********************************************************************************************************************
// Descripcion : Verifica si el producto tiene errores en costos / existencias
// Entrada : 			atProducto	-	Registro del producto a verificar
// Salida  :		
// *********************************************************************************************************************
Deffunc fVerificaErrorCostoExistencia(atProducto:Tabla)
Local	lExistenciaCongelada

	// Limpia el código de error
	gCodigoError = ' '

	// 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)
  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 )
		gErrorEnCostos = 1
    gCodigoError 	= '('  & atProducto(cErrorCosto) & ')'
  FinSi 

  // Si hay movtos sin afectar y no hay errores de costos O los movtos sin afectar ocurrieron antes del error de costos
  // entonces se despliega el error de movtos sin afectar
  Si ( lFechaSinAfectar Y !atProducto(cErrorCosto) ) O ( lFechaSinAfectar Y atProducto(cErrorCosto) Y lFechaSinAfectar <= atProducto(cFechaErrorCosto) )
		gErrorEnCostos = 1
		gCodigoError = '(6)'
  FinSi

Finfunc



// *********************************************************************************************************************
// Descripción:	Esta función imprime los datos del producto
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeMovimiento(atMovimiento:Tabla; atDocumento:Tabla; atProducto:Tabla)
Local lImprime, lImporte, lNetoMenosDescuentos, lCostoMovimiento
Local lIdMonedaCliente
Local lTipoES //N.D. 7572

  // Obtención de la moneda del cliente / proveedor
  tClienteProveedor.Busca[@Str(atDocumento(cIdClienteProveedor);0)]
  Si tClienteProveedor->Encontro
    lIdMonedaCliente = tClienteProveedor(cIdMoneda)
  Sino
    lIdMonedaCliente = atDocumento(cIdMoneda)
  FinSi
  
	lImporte = 0
	lImprime = ' '

	// Unidades
	lImprime[gColUnidades] = atMovimiento(cUnidades)
	lImporte[gColUnidades] = @Col(lImprime; gColUnidades)

	// Gastos
	lGastoUnitario = 0.0
	Si atDocumento(cIdDocumentoDe) = 19	// Documento de compra, calcular sus gastos?
		lNetoMenosDescuentos = atMovimiento(cNeto) - atMovimiento(cDescuento1) - atMovimiento(cDescuento2) - atMovimiento(cDescuento3) - atMovimiento(cDescuento4) - atMovimiento(cDescuento5)
		lGastoTotal 	 = atDocumento(cGasto1) + atDocumento(cGasto2) + atDocumento(cGasto3)
		lGastoUnitario = lGastoTotal * lNetoMenosDescuentos
		lGastoUnitario = lGastoUnitario / (atDocumento(cNeto) - atDocumento(cDescuentoMov))
	FinSi
	lImprime[gColGastos] = fCambiarMonedaImporteAReporte(atDocumento; tTiposCambioLib; lGastoUnitario; 1; pIdMonedaReporte; lIdMonedaCliente)
	lImporte[gColGastos] = @Col(lImprime; gColGastos)

  // A fin de evitar que los reportes y los acumulados muestren información diferente de costos SIEMPRE se toma el
  //  costo del costo especifico del Movimiento; el cual está en moneda base
  lCostoMovimiento = atMovimiento(cCostoEspecifico)
  lImprime[gColTotal] = fCambiarMonedaImporteAReporte(atDocumento; tTiposCambioLib; lCostoMovimiento; 1; pIdMonedaReporte; lIdMonedaCliente)
	lImporte[gColTotal] = @Col(lImprime; gColTotal)

  //N.C.224 Si el parámetro de tiene movimientos solo afectados en existencias es verdadero entonces imprime (8)
	Si gTieneMovtosEnCaptura = 1 Y pDetallado = 1			
		lImprime = '(8)'[C20]
		gTieneMovtosEnCaptura = 0	
	FinSi

	Si pDetallado = 1
		// Fecha
		lImprime = @Col(fFormateaFecha(atDocumento(cFecha); gIdioma);0)[C1]
		// Documento Modelo
	  tDoctoModelo.Busca[@Str(atDocumento(cIdDocumentoDe);0)]
		lImprime = @Col(tDoctoModelo(cDescripcion);0)[C3]
		// Serie
		lImprime = @Col(atDocumento(cSerieDocumento);0)[C5]
		// Folio
		lImprime = @Col(atDocumento(cFolio);0)[C7]
		// Codigo producto
		lImprime = @Col(fMascarilla(atProducto(cCodigoProducto); gMascarillaProducto);0)[C9]
		// Nombre producto
		lImprime = @Col(atProducto(cNombreProducto);0)[C11]
			// Error
		lImprime[gColError] = gCodigoError
		//Lista lImprime
		//N.D. 7572
		lTipoES = atMovimiento(cAfectaExistencia)
		Si lTipoES = 1 //Entrada
			lImprime = 'Entrada' [C19]
		SiNo
			Si lTipoES = 2 //Salida
				lImprime = 'Salida' [C19]
			SiNo //Ninguno
				lImprime = 'Ninguno' [C19]
			FinSi
		FinSi
		Lista lImprime
		//Fin N.D. 7572
	FinSi
	
	gReporteConMovimientos = 1

  // Los movimientos de salidan restan los importes y/o cantidades
  Si atMovimiento(cAfectaExistencia) = 2 // Salidas
    lImporte = lImporte * -1
  FinSi

	// Acumulados
	gTotalConcepto	= gTotalConcepto	+ lImporte
	gTotalAlmacen 	= gTotalAlmacen 	+ lImporte
	gTotalReporte		= gTotalReporte		+ lImporte
FinFunc


// *********************************************************************************************************************
// Descripción:	Esta función imprime los datos del almacén
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeConcepto(atConcepto:Tabla)
Local lImprime

	Si gImpresoConcepto
		Retorna
	FinSi

	Si pDetallado = 1
		Columnas 6;0.10,1.80,0.15,3.50,0.15,1.00,0
	 	lImprime = ' '

	  // Codigo
 		lImprime = atConcepto(cCodigoConcepto)[C1]
		//lImprime = 'Linea de prueba' [C6]
	 	lImprime = atConcepto(cNombreConcepto)[C3]
		tDoctoModelo.Busca[@Str(atConcepto(cIdDocumentoDe);0)]
		Si tDoctoModelo(cAfectaExistencia) = 1      
 			lImprime = 'Entradas'[C5]
		Sino
	 		lImprime = 'Salidas'[C5]
		FinSi
    // En caso de ser una remisión, devolución de remisión o traspaso se pone como tipo el nombre del documento modelo
    Si tDoctoModelo(cIdDocumentoDe) = 3 O tDoctoModelo(cIdDocumentoDe) = 6 O tDoctoModelo(cIdDocumentoDe) = 34
	 		lImprime = tDoctoModelo(cDescripcion)[C5]
    FinSi 
		Lista lImprime
		gImpresoConcepto = 1
		Si pDetallado = 0
		//N.C.224
			Columnas 16;0.15,2.25,0.25,5.50,0.25,2.00,0.25,1.80,0.25,2.25,0.25,2.25,0.50,1.00,0.50,0.15
		Sino
			//Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.15,0.75,0.50,0.15
			Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.15,1.75,0.50,0.15
		FinSi
	FinSi
FinFunc


// *********************************************************************************************************************
// Descripción:	Esta función imprime los datos del almacén
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeAlmacen(atAlmacen:Tabla)
Local lImprime, lCodigoEditado

	Si gImpresoAlmacen
		Retorna
	FinSi

	Columnas 5;1.50,0.15,6.00,0
 	lImprime = ' '

  // Codigo
 	lCodigoEditado = fMascarilla(atAlmacen(cCodigoAlmacen); gMascarillaAlmacen)
	lImprime = 'Almacén:'[C0]
 	lImprime = @Col(lCodigoEditado;0)[C2]
  Lista lImprime
	// Nombre
  lImprime = 'Nombre:'[C0]
 	lImprime = atAlmacen(cNombreAlmacen)[C2]
  Lista lImprime
	gImpresoAlmacen = 1
	Saltalin

	Si pDetallado = 0
	//N.C.224
		Columnas 16;0.15,2.25,0.25,5.50,0.25,2.00,0.25,1.80,0.25,2.25,0.25,2.25,0.50,1.00,0.50,0.15
	Sino
		//Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.15,0.75,0.50,0.15
		//N.D. 7572
		Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,3.00,0.75,0.50,0.15
	FinSi
FinFunc


// *********************************************************************************************************************
// Descripción:	Esta función imprime los totales del concepto
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeTotalConcepto (atConcepto:Tabla)
Local lImprime

	lImprime = ' '	

	Si pDetallado = 0
	  // Codigo concepto
 		lImprime = atConcepto(cCodigoConcepto)[C1]
		// Nombre concepto
	 	lImprime = atConcepto(cNombreConcepto)[C3]
		tDoctoModelo.Busca[@Str(atConcepto(cIdDocumentoDe);0)]
		// Tipo
		Si tDoctoModelo(cAfectaExistencia) = 1
 			lImprime = 'Entradas'[C5]
		Sino
	 		lImprime = 'Salidas'[C5]
		FinSi
    // En caso de ser una remisión, devolución de remisión o traspaso se pone como tipo el nombre del documento modelo
    Si tDoctoModelo(cIdDocumentoDe) = 3 O tDoctoModelo(cIdDocumentoDe) = 6 O tDoctoModelo(cIdDocumentoDe) = 34
	 		lImprime = tDoctoModelo(cDescripcion)[C5]
    FinSi
		//
		lImprime[gColUnidades]	= @Col(gTotalConcepto; gColUnidades)	// Unidades
		lImprime[gColGastos]		= @Col(gTotalConcepto; gColGastos)		// Gastos
		lImprime[gColTotal]			= @Col(gTotalConcepto; gColTotal)			// Costo total3
		lImprime[gColError]			= @Col(gCodigoError; 0)								// Error
    DEFREGION ContextoDetalleAlmacenCpto
    Si @Col(gTotalConcepto; gColUnidades) != 0 O @Col(gTotalConcepto; gColGastos) != 0 O @Col(gTotalConcepto; gColTotal) != 0
      [C3].REGIONINFO tAlmacen(cCodigoAlmacen) & ',' & atConcepto(cIdConceptoDocumento) 
    FinSi
    //N.C.224
    Si gTieneMovtosEnCaptura = 1
    	Si pDetallado = 0
    		lImprime = '(*)'[C14] //MAJU
    	FinSi
    Finsi  
		Lista lImprime
    gTieneMovtosEnCaptura = 0
    lImprime = ' '[C14] //MAJU
		
	Sino
		lImprime [gColUnidades] = '_______________________________________________________'
		lImprime [gColGastos] = '_______________________________________________________'
		lImprime [gColTotal] = '_______________________________________________________'
		Lista lImprime
		lImprime = ' '	
		lImprime[gColLeyenda] 	= 'Total Concepto'		// Leyenda
		lImprime[gColUnidades]	= @Col(gTotalConcepto; gColUnidades)			// Unidades
		lImprime[gColGastos]		= @Col(gTotalConcepto; gColGastos)				// Gastos
		lImprime[gColTotal]			= @Col(gTotalConcepto; gColTotal)				// Costo total
		Lista lImprime
		Saltalin 1
	FinSi
FinFunc


// *********************************************************************************************************************
// Descripción:	Esta función imprime los totales del almacén
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeTotalAlmacen (atAlmacen:TABLA)
Local lImprime

	lImprime = ' '	
	lImprime [gColUnidades] = '_______________________________________________________'
	lImprime [gColGastos] = '_______________________________________________________'
	lImprime [gColTotal] = '_______________________________________________________'
	Lista lImprime
	lImprime = ' '	
	lImprime[gColLeyenda] 	= 'Total Almacén'		// Leyenda
	lImprime[gColUnidades]	= @Col(gTotalAlmacen; gColUnidades)			// Unidades
	lImprime[gColGastos]		= @Col(gTotalAlmacen; gColGastos)				// Gastos
	lImprime[gColTotal]			= @Col(gTotalAlmacen; gColTotal)				// Costo total
	
	Lista lImprime
	Saltalin 2
FinFunc


// *********************************************************************************************************************
// Descripción:	Esta función imprime los totales generales
// Parámetros 
// Salidas 
// *********************************************************************************************************************
DefFunc fImprimeTotalReporte ()
Local lImprime

	lImprime = ' '	
	lImprime [gColUnidades] = '_______________________________________________________'
	lImprime [gColGastos] = '_______________________________________________________'
	lImprime [gColTotal] = '_______________________________________________________'
	Lista lImprime
	lImprime = ' '	
	lImprime [gColLeyenda] 	= 'Total Reporte'		// Leyenda
	lImprime[gColUnidades]	= @Col(gTotalReporte; gColUnidades)			// Unidades
	lImprime[gColGastos]		= @Col(gTotalReporte; gColGastos)				// Gastos
	lImprime[gColTotal]			= @Col(gTotalReporte; gColTotal)				// Costo total
	Lista lImprime
FinFunc


// *********************************************************************************************************************
// E N C A B E Z A D O
// *********************************************************************************************************************
Encab
	Texto '@TC{255,0,0}@S{8}AdminPAQ'
	Hoja '"@TC{0,0,0}@S{8}Hoja: '
	Imprime
  Texto '@TC{0,0,0}@S{8}Moneda: ' & gNombreMonedaReporte
  Texto '"@TC{0,0,0}@S{8}Fecha: ' & fFormateaFecha(@Hoy();gIdioma)
 	Imprime
	Texto '^@TC{0,0,0}@S{22}' & tEmpresa->Nombre
	Imprime
	Si pDetallado = 0
		Texto '^@TC{0,0,0}@S{16}MOVIMIENTOS DEL ALMACEN POR CONCEPTO'
	Sino
		Texto '^@TC{0,0,0}@S{16}MOVIMIENTOS DETALLADOS DEL ALMACEN POR CONCEPTO'
	FinSi
	Imprime
	Texto '^@TC{0,0,0}@S{16}Del: ' & fFormateaFecha(pFechaInicial; gIdioma) & ' Al: ' & fFormateaFecha(pFechaFinal; gIdioma)
	Imprime
	// Estado del producto
	Si pEstadoProducto != 0
		Si pEstadoProducto = 1
  		Texto '^@TC{0,0,0}@S{12}Productos Activos'
		Sino
  		Texto '^@TC{0,0,0}@S{12}Productos Inactivos'
		FinSi
		Imprime
	FinSi
  Saltalin
	NEGRITAS TRUE
	Texto '@TC{0,0,0}@L{-1}'
  Imprime
	Si pDetallado = 0	
		Texto C1;'Codigo Concepto'
		Texto C3;'Nombre Concepto'
		Texto C5;'Tipo'
		Texto C7;'Unidades'
		Texto C9;'Gastos'
		Texto C11;'Costo Total'
		Texto C13;' '
	Sino
		Columnas 6;0.10,1.80,0.15,3.50,0.15,1.00,0
		Texto C1;'Codigo'
		Texto C3;'Nombre Concepto'
		Texto C5;'Tipo'
		Imprime
		//N.C.224
		//Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.15,0.75,0.50,0.15
		//N.D. 7275 
		Columnas 22;0.00,1.80,0.15,3.00,0.15,0.75,0.15,1.80,0.15,1.50,0.15,3.75,0.15,1.50,0.15,2.00,0.15,2.00,0.10,1.75,1.50,0.15
		Texto C1;'Fecha'
		Texto C3;'Documento Modelo'
		Texto C5;'Serie'
		Texto C7;'Folio'
		Texto C9;'Producto'
		Texto C11;'Nombre'
		Texto C13;'Unidades'
		Texto C15;'Gastos'
		Texto C17;'Costo Total'
		//Texto C19;' '
		Texto C19;'Tipo mov'
		Texto C21;' '  //N.D. 7275 FPP
	FinSi
	Imprime
	Texto '@TC{0,0,0}@L{-1}'
	Imprime 1
	NEGRITAS FALSE
	Color @RGB(0;0;0)
	Altura 9
FinEncab


/*------------------------------------------------------------------------------
// Nombre:  Cuerpo del reporte
// Proceso: 
// Entradas:
// Salidas:

// Consideraciones:

// Historia de Revisiones:
//  Fecha             ID-Lotus        Descripción
//--------------------------------------------------------------------------------
//  05/02/2008        N.D.5062        Se cambia de indice (JENL).
//--------------------------------------------------------------------------------
------------------------------------------------------------------------------*/

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

	// Configura los decimales del reporte y las mascarillas
	fConfiguraDecimalesyMascaras()

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

	// A partir de la fecha de inicio del reporte, obtiene el ejercicio y periodo correspondiente
	// esto es util para el cálculo del inventario inicial del reporte
	fEjercicioPeriodo(pFechaInicial; &gPeriodo; &gIdEjercicio; tEjercicio) 

	gTotalReporte	= 0.0

	Mientras[tAlmacen.Busca[pAlmacenInicial & '..' & pAlmacenFinal]; tAlmacen->Encontro; tAlmacen.Busca Siguiente[1]]
		// Descarta el Almacén 0
		Si tAlmacen(cIdAlmacen) = 0
			Continua
		FinSi

		// Impresión de los datos del almacen
		gImpresoAlmacen = 0						// Bandera para indicar que ya se imprimio el almacén
		gTotalAlmacen		= 0.0					// Acumulados por almacén
		gAlmacenConMovimientos = 0		// Bandera para indicar que el almacén tiene movimientos
		fImprimeAlmacen(tAlmacen)

		lConceptoActual = 0
		Mientras lConceptoActual < gNumeroConceptos
			// Toma el concepto y valida que exista en la empresa
			lIdConcepto = @Escoge(pListaConceptos; lConceptoActual)
			tConceptoDocto.Busca[lIdConcepto]
			Si !tConceptoDocto->Encontro
				lConceptoActual = lConceptoActual + 1
				Continua	
			FinSi
			// Fin validación del concepto

			gImpresoConcepto = 0					// Bandera para indicar que ya se imprimio el concepto
			gTotalConcepto	 = 0.0				// Acumulados por concepto
			gConceptoConMovimientos = 0		// Bandera para indicar que el concepto tiene movimientos
			Si pImprimirConceptos = 0 		// Imprime el concepto aunque no tenga movimientos
  		  fImprimeConcepto(tConceptoDocto)
			FinSi
			
			// Valida que existan documentos del concepto actual en el rango de fechas
      // Búsqueda de un movimiento del producto a la fecha inicial del reporte
      gFechaBusqueda = pFechaInicial
      // NOTA: Es obligatorio volver a fijar el índice a fin de que las búsquedas parciales funcionen correctamente
      tDoctoAuxiliar.Usaindice['iConceptoFecha']
      tDoctoAuxiliar.Busca[tConceptoDocto(cIdConceptoDocumento) & ':' & gFechaBusqueda]
      Si !tDoctoAuxiliar->ENCONTRO
        // Busquedas parciales: Cursor en el registro más cercano que cumple con la llave
        // NOTA: La propiedad Llave de la tabla nos regresa la llave más cercana que cumple con el criterio de la búsqueda
        //       La llave está en formato cadena y no tiene ningún separador entre los campos, por lo que es necesario revisar
        //      en FoxPro la definición del índice para descomponer los elementos de la Llave
        Si tConceptoDocto(cIdConceptoDocumento) = @Val(@SUBSTR(tDoctoAuxiliar->Llave;0;11))
          Si @SUBSTR(tDoctoAuxiliar->Llave;11;8) >= pFechaInicial Y @SUBSTR(tDoctoAuxiliar->Llave;11;8) <= pFechaFinal
            // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro                
            gFechaBusqueda = @SUBSTR(tDoctoAuxiliar->Llave;11;8)
            tDoctoAuxiliar.Busca[tConceptoDocto(cIdConceptoDocumento) & ':' & gFechaBusqueda]
          FinSi
        FinSi        
      FinSi
      Si tDoctoAuxiliar->ENCONTRO
        // En caso de encontrar conceptos recorrer por producto
  			// Recorre todos los productos
	  		Mientras[tProducto.Busca[gProductoInicial & '..' & gProductoFinal]; tProducto->Encontro; tProducto.Busca Siguiente[1]]
		  		// No incluye el producto 0
			  	Si tProducto(cIdProducto) = 0
				  	Continua
  				FinSi

	  			// Obtención del codigo de error en costos y/o existencia, se guarda en gCodigoError
		  		// Solo para el reporte detallado
			  	Si pDetallado = 1
				  	fVerificaErrorCostoExistencia(tProducto)
				  FinSi

          // Búsqueda de un movimiento del producto a la fecha inicial del reporte
          gFechaBusqueda = pFechaInicial
          // NOTA: Es obligatorio volver a fijar el índice a fin de que las búsquedas parciales funcionen correctamente
          tMovimiento.Usaindice['iProductoAlmacenFechaAfec']
          tMovimiento.Busca[tProducto(cIdProducto) & ':' & tAlmacen(cIdAlmacen) & ':' & gFechaBusqueda]
          Si !tMovimiento->ENCONTRO          	
            // Busquedas parciales: Cursor en el registro más cercano que cumple con la llave
            // NOTA: La propiedad Llave de la tabla nos regresa la llave más cercana que cumple con el criterio de la búsqueda
            //       La llave está en formato cadena y no tiene ningún separador entre los campos, por lo que es necesario revisar
            //      en FoxPro la definición del índice para descomponer los elementos de la Llave
            Si tProducto(cIdProducto) = @Val(@SUBSTR(tMovimiento->Llave;0;11))
              Si tAlmacen(cIdAlmacen) = @Val(@SUBSTR(tMovimiento->Llave;11;11))
                Si @SUBSTR(tMovimiento->Llave;22;8) >= pFechaInicial Y @SUBSTR(tMovimiento->Llave;22;8) <= pFechaFinal
                  // Realizar nuevamente la búsqueda a fin de posicionarnos en el registro y activar la propiedad Encontro
                  gFechaBusqueda = @SUBSTR(tMovimiento->Llave;22;8)
                  tMovimiento.Busca[tProducto(cIdProducto) & ':' & tAlmacen(cIdAlmacen) & ':' & gFechaBusqueda]
                FinSi
              FinSi
            FinSi        
          FinSi

          // Recorrer los movimientos hasta que sea diferente producto, almacén o se rompa el rango de fechas
          Mientras tMovimiento->Encontro Y (tMovimiento(cFecha) <= pFechaFinal)
		  			// No considerar los no afectados		  			
		  			
            //N.C.224 Movimientos sin afectar
            //Se deben considerar las unidades que afectaron el inventario 
            //aunque todavía no se afecte el costo, esto sucede cuando todavía se tienen 
            //movimientos en captura.        
			  		Si tMovimiento(cAfectadoInventario)	= 0
              //Búsqueda del siguiente registro que cumpla con el producto / almacén
              tMovimiento.BUSCA SIGUIENTE[2]
						  Continua
  					FinSi
  					
	  				// No considerar los movimientos que no afecten inventarios
		  			Si tMovimiento(cAfectaExistencia) = 3
              // Búsqueda del siguiente registro que cumpla con el producto / almacén
              tMovimiento.BUSCA SIGUIENTE[2]
					  	Continua
  					FinSi

            // Discrimina movimientos incompletos de características
            // Revisa si el movimiento corresponde a un detalle de características
            Si tMovimiento(cTipoTraspaso) = 4
              // Busca el producto identificador
              tDetalleProducto.Busca[@Str(tMovimiento(cIdProducto);0)]
              Si tDetalleProducto->Encontro
    	          // Si el producto corresponde a un padre de características, entonces
  	            //  no hay que procesar este movimiento ya que es un movto incompleto de características
                Si tDetalleProducto(cTipoProducto) = 0
                  // Búsqueda del siguiente registro que cumpla con el producto / almacén
                  tMovimiento.BUSCA SIGUIENTE[2]
                  Continua
                FinSi
              FinSi
            FinSi

            // Obtención del Documento al que pertenece el movimiento
            Si tMovimiento(cIdDocumento)
              tDocumento.Busca[@Str(tMovimiento(cIdDocumento);0)]
            Sino // es un movimiento oculto
              // Busca el ID del documento en el movimiento owner
              Si tMovimiento(cIdMovtoOwner)
                // Busca el movimiento owner
                tMovtoSinAfectar.Busca[@Str(tMovimiento(cIdMovtoOwner);0)] 
                Si tMovtoSinAfectar->Encontro
                  tDocumento.Busca[@Str(tMovtoSinAfectar(cIdDocumento);0)]
                FinSi
              FinSi
            FinSi
    				Si !tDocumento->Encontro
              // Búsqueda del siguiente registro que cumpla con el producto / almacén
              tMovimiento.BUSCA SIGUIENTE[2]
			  			Continua
				  	FinSi

					  // Descartar los movimientos que no sean del concepto
  					Si tDocumento(cIdConceptoDocumento) != lIdConcepto
              // Búsqueda del siguiente registro que cumpla con el producto / almacén
              tMovimiento.BUSCA SIGUIENTE[2]
			  			Continua
				  	FinSi

            //N.C.224
            Si tMovimiento(cAfectadoInventario)	= 2
              gTieneMovtosEnCaptura = 1 
            Sino
              gTieneMovtosEnCaptura = 0
            FinSi
            
  					// Solo se imprime el concepto si tiene movimientos
	  				Si gImpresoConcepto = 0
		  				fImprimeConcepto(tConceptoDocto)
			  		FinSi

				  	// Impresión del movimiento
					  gConceptoConMovimientos = 1
					  //N.C.224
  					fImprimeMovimiento(tMovimiento; tDocumento; tProducto)

            // Búsqueda del siguiente registro que cumpla con el producto / almacén
            tMovimiento.BUSCA SIGUIENTE[2]
			  	FinMientras
  			FinMientras
	  		// Fin Recorrido de productos	 		  
	  	FinSi

			Si pImprimirConceptos = 0 o (pImprimirConceptos y gConceptoConMovimientos)
				fImprimeTotalConcepto(tConceptoDocto)
			FinSi
			lConceptoActual = lConceptoActual + 1
		FinMientras
		// Fin Rango de conceptos	

		fImprimeTotalAlmacen(tAlmacen)
	FinMientras 
	// Fin Recorrido de Almacenes

	// Impresión de los totales del reporte
	fImprimetotalReporte()

	// Impresión de pie de pagina
	// Solo si es detallado tiene errores y tiene movimientos.
	//	(el concentrado no despliega mensajes de error)
	Si pDetallado = 1 y gErrorEnCostos = 1 y gReporteConMovimientos = 1
		Columnas 4;0.50,20,0.0
  	Saltalin 2

	  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 movimiento está actualmente en captura, por tal motivo 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]
	FinSi
	//Inicio N.C.224
	Si pDetallado = 0
		Columnas 4;0.50,20,0.0
  	Saltalin 2
  	Lista '', 'Errores de existencias o costos:'[C1]
  	Lista '', ' (*) Este movimiento está actualmente en captura, por tal motivo solo está afectado en existencia y no en costo'[C1]
  	Lista '', 'En este caso se recomienda consultar el reporte en cuanto se termine de capturar el documento'[C1]
	FinSi
	//Fin N.C.224
