예제 #1
0
        /// <summary>
        /// Agrega un error nuevo a la lista de errores del resultado de validación
        /// </summary>
        /// <param name="resultadoValidcion">Objeto de resultado donde se colocará el error</param>
        /// <param name="codigo">Código opcional de error</param>
        /// <param name="idContexto">Identificador opcional de contexto del error</param>
        /// <param name="mensaje">Mensaje de error</param>
        /// <param name="borrarOtrosErrores">Indica si se deben de limpiar otros errores y agregar solo este error</param>
        protected void AgregarError(ResultadoValidacionDocumentoXBRLDto resultadoValidcion, String codigo, string idContexto, String mensaje, bool borrarOtrosErrores)
        {
            if (borrarOtrosErrores)
            {
                resultadoValidcion.ErroresGenerales.Clear();
            }
            var error = new ErrorCargaTaxonomiaDto()
            {
                CodigoError = codigo,
                IdContexto  = idContexto,
                Mensaje     = mensaje,
                Severidad   = ErrorCargaTaxonomiaDto.SEVERIDAD_ERROR
            };

            resultadoValidcion.Valido = false;

            if (idContexto == null)
            {
                resultadoValidcion.ErroresGenerales.Add(error);
            }
            else
            {
                var validacionPeriodo = resultadoValidcion.Periodos.FirstOrDefault(x => x.IdContextos != null && x.IdContextos.Contains(idContexto));
                if (validacionPeriodo != null)
                {
                    validacionPeriodo.Errores.Add(error);
                }
                else
                {
                    resultadoValidcion.ErroresGenerales.Add(error);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Agrega un nuevo error a la lista de errores del objeto de resultado
        /// </summary>
        /// <param name="resultado">Objeto de resultado al cuál se agrega el error</param>
        /// <param name="codigo">Código opcional del error</param>
        /// <param name="idContexto">Identificador del contexto donde se presenta el error</param>
        /// <param name="idHecho">Identificador del hecho donde se presenta el error</param>
        /// <param name="mensaje">Mensaje de error</param>
        protected void AgregarErrorFatal(ResultadoValidacionDocumentoXBRLDto resultado, String codigo, string idContexto, String idHecho, string mensaje)
        {
            resultado.Valido = false;
            var nuevoError = new ErrorCargaTaxonomiaDto();

            nuevoError.CodigoError = codigo;
            nuevoError.IdContexto  = idContexto;
            nuevoError.IdHecho     = idHecho;
            nuevoError.Mensaje     = mensaje;
            nuevoError.Severidad   = ErrorCargaTaxonomiaDto.SEVERIDAD_FATAL;
            resultado.ErroresGenerales.Add(nuevoError);
        }
예제 #3
0
        /// <summary>
        /// Procesa el documento de instancia que se encuentra dentro del archivo ZIP enviado como parámetro
        /// </summary>
        /// <param name="archivo"></param>
        /// <param name="resultadoValidacion"></param>
        /// <returns></returns>
        private void ProcesarArchivoZip(String rutaAbsolutaArchivo, ResultadoValidacionDocumentoXBRLDto resultadoValidacion, IDictionary <string, string> parametros)
        {
            DocumentoInstanciaXbrlDto documentoXbrl = null;
            string        archivoXbrl = null;
            DirectoryInfo tmpDir      = null;

            try
            {
                using (var zipFile = ZipFile.Read(rutaAbsolutaArchivo))
                {
                    tmpDir = UtilAbax.ObtenerDirectorioTemporal();
                    zipFile.ExtractAll(tmpDir.FullName, ExtractExistingFileAction.OverwriteSilently);
                    if (zipFile.Count == 1)
                    {
                        foreach (var archivoInterno in zipFile)
                        {
                            if (!archivoInterno.IsDirectory &&
                                archivoInterno.FileName.ToLower().EndsWith(CommonConstants.ExtensionXBRL))
                            {
                                archivoXbrl = archivoInterno.FileName;
                            }
                        }
                    }
                    if (archivoXbrl == null)
                    {
                        AgregarErrorFatal(resultadoValidacion, null, null, null, "Debe existir un archivo dentro del archivo ZIP y debe tener la extensión XBRL");
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.Error(ex);
                AgregarErrorFatal(resultadoValidacion, null, null, null, "Ocurrió un error al leer el archivo ZIP: " + ex.Message);
            }
            if (archivoXbrl != null)
            {
                try
                {
                    var uriArchivo = new Uri(tmpDir.FullName + Path.DirectorySeparatorChar + archivoXbrl, UriKind.Absolute);
                    ProcesarArchivoXBRL(uriArchivo.AbsolutePath, resultadoValidacion, parametros);
                }
                catch (Exception ex)
                {
                    LogUtil.Error(ex);
                    AgregarErrorFatal(resultadoValidacion, null, null, null, "Ocurrió un error al leer el archivo XBRL: " + ex.Message);
                }
                finally
                {
                    documentoXbrl = null;
                }
            }
        }
예제 #4
0
 public abstract void ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion);
예제 #5
0
        /// <summary>
        /// Consume los hechos del documento de instancia para organizar los periodos reportados en el archivo, las unidades utilizadas
        /// y la entidad que reporta la información
        /// </summary>
        /// <param name="documentoXbrl">Documento XBRL de origen</param>
        /// <param name="resultadoValidcion">Objeot donde se llenará el resumen de los periodos</param>
        private void CrearResumenDePeriodos(DocumentoInstanciaXbrlDto documentoXbrl, ResultadoValidacionDocumentoXBRLDto resultadoValidcion)
        {
            var mapaPeriodos = new Dictionary <String, ResumenValidacionPeriodoXBRLDto>();

            foreach (var hecho in documentoXbrl.HechosPorId.Values)
            {
                if (hecho.IdContexto != null && documentoXbrl.ContextosPorId.ContainsKey(hecho.IdContexto))
                {
                    var contexto = documentoXbrl.ContextosPorId[hecho.IdContexto];
                    ResumenValidacionPeriodoXBRLDto resumenPeriodo = null;
                    String llavePeriodo = null;
                    if (contexto.Periodo.Tipo == PeriodoDto.Duracion)
                    {
                        llavePeriodo = DateUtil.ToStandarString(contexto.Periodo.FechaInicio) + "-" + DateUtil.ToStandarString(contexto.Periodo.FechaFin);
                    }
                    else if (contexto.Periodo.Tipo == PeriodoDto.Instante)
                    {
                        llavePeriodo = DateUtil.ToStandarString(contexto.Periodo.FechaInstante);
                    }
                    else
                    {
                        llavePeriodo = "Para siempre";
                    }

                    llavePeriodo += "-" + contexto.Entidad.Id;

                    if (!mapaPeriodos.ContainsKey(llavePeriodo))
                    {
                        resumenPeriodo = new ResumenValidacionPeriodoXBRLDto()
                        {
                            Entidad     = contexto.Entidad.Id,
                            Errores     = new List <ErrorCargaTaxonomiaDto>(),
                            IdContextos = new List <String>(),
                            TipoPeriodo = (short)contexto.Periodo.Tipo,
                            Unidades    = new List <String>()
                        };
                        if (contexto.Periodo.Tipo == PeriodoDto.Duracion)
                        {
                            resumenPeriodo.FechaInicio = contexto.Periodo.FechaInicio;
                            resumenPeriodo.FechaFin    = contexto.Periodo.FechaFin;
                        }
                        else if (contexto.Periodo.Tipo == PeriodoDto.Instante)
                        {
                            resumenPeriodo.FechaFin = contexto.Periodo.FechaInstante;
                        }
                        mapaPeriodos.Add(
                            llavePeriodo, resumenPeriodo
                            );
                    }

                    resumenPeriodo = mapaPeriodos[llavePeriodo];
                    if (!resumenPeriodo.IdContextos.Contains(hecho.IdContexto))
                    {
                        resumenPeriodo.IdContextos.Add(hecho.IdContexto);
                    }
                    if (hecho.IdUnidad != null && documentoXbrl.UnidadesPorId.ContainsKey(hecho.IdUnidad))
                    {
                        var    unidad  = documentoXbrl.UnidadesPorId[hecho.IdUnidad];
                        String moneda  = null;
                        var    medidas = new List <MedidaDto>();
                        if (unidad.Tipo == UnidadDto.Medida)
                        {
                            medidas.AddRange(unidad.Medidas);
                        }
                        else
                        {
                            medidas.AddRange(unidad.MedidasNumerador);
                            medidas.AddRange(unidad.MedidasDenominador);
                        }
                        foreach (var medida in medidas)
                        {
                            if (medida.EspacioNombres.Equals(EspacioNombresConstantes.ISO_4217_Currency_Namespace))
                            {
                                moneda = medida.Nombre;
                                break;
                            }
                        }
                        if (moneda != null && !resumenPeriodo.Unidades.Contains(moneda))
                        {
                            resumenPeriodo.Unidades.Add(moneda);
                        }
                    }
                }
            }
            resultadoValidcion.Periodos = mapaPeriodos.Values.ToList();
        }
예제 #6
0
 /// <summary>
 /// Valida la codificación del archivo enviado a ISO-8859-1
 /// </summary>
 /// <param name="streamArchivo">Stream original del archivo</param>
 /// <param name="documentoXbrl">Documento XBRL transformado</param>
 /// <param name="parametros">Parametros de configuración de la validación</param>
 /// <param name="resultadoValidacion">Objeto de resultado de validación</param>
 private void ValidarCodificacion(Stream streamArchivo, DocumentoInstanciaXbrlDto documentoXbrl, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
 {
     if (!CodificacionRequerida.Equals(documentoXbrl.Codificacion, StringComparison.InvariantCultureIgnoreCase))
     {
         AgregarErrorFatal(resultadoValidacion, null, null, null, "El archivo no contiene un documento instancia XBRL bien formado y por lo tanto no pudo ser validado, verifique la codificación del archivo");
         return;
     }
     if (streamArchivo != null)
     {
         byte[] primerosBytes = new byte[10];
         streamArchivo.Position = 0;
         //Leer primeros 10 bytes
         streamArchivo.Read(primerosBytes, 0, 10);
         //Para buscar los primeros bytes de marca de orden que indicarían que el archivo es UTF-8 con BOM
         bool coincideUTF = false;
         for (int iIndicador = 0; iIndicador < INDICADORES_UTF.Length; iIndicador++)
         {
             if (primerosBytes.Length >= INDICADORES_UTF[iIndicador].Length)
             {
                 coincideUTF = true;
                 //Comparar si la cadena de bytes inicia con los indicadores
                 for (int iPosIndicador = 0; iPosIndicador < INDICADORES_UTF[iIndicador].Length; iPosIndicador++)
                 {
                     if (primerosBytes[iPosIndicador] != INDICADORES_UTF[iIndicador][iPosIndicador])
                     {
                         coincideUTF = false;
                         break;
                     }
                 }
                 if (coincideUTF)
                 {
                     break;
                 }
             }
         }
         if (coincideUTF)
         {
             AgregarErrorFatal(resultadoValidacion, null, null, null, "El archivo no contiene un documento instancia XBRL bien formado y por lo tanto no pudo ser validado, verifique la codificación del archivo");
         }
     }
 }
예제 #7
0
        public override void ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            LogUtil.Info("Validando reglas REPORTE ANUAL para:" + instancia.NombreArchivo);
            if (!ESPACIOS_NOMBRE.ContainsKey(instancia.EspacioNombresPrincipal))
            {
                throw new Exception("Documento de instancia a validar no corresponde a ninguna taxonomía de Prospecto (" + instancia.EspacioNombresPrincipal + ")");
            }

            String cvePizarra;

            if (!parametros.TryGetValue(PARAMETRO_CLAVE_PIZARRRA, out cvePizarra) || String.IsNullOrEmpty(cvePizarra))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, PARAMETRO_CLAVE_PIZARRRA), true);
                return;
            }
            String parametrofechaColocacion;

            if (!parametros.TryGetValue(PARAMETRO_FECHA_COLOCACION, out parametrofechaColocacion) || String.IsNullOrEmpty(parametrofechaColocacion))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, PARAMETRO_FECHA_COLOCACION), true);
                return;
            }

            //Int32 anio;
            //if (!Int32.TryParse(parametrofechaColocacion.Trim(), out anio))
            //{
            //    AgregarError(resultadoValidacion, null, null, String.Format("El periodo indicado ({0}) no es valido para la taxonomía de prospecto.", valorPeroiodo), true);
            //    return;
            //}


            var aliasClaveCotizacion = ObtenerAliasEmpresa(cvePizarra);

            if (aliasClaveCotizacion != null)
            {
                LogUtil.Info("{clavePizarra:[" + cvePizarra + "], alias: [" + aliasClaveCotizacion + "]}");
                cvePizarra = aliasClaveCotizacion;
            }
            LogUtil.Info("{clavePizarra:[" + cvePizarra + "]}");
            var    plantilla           = new AbaxXBRLCore.Viewer.Application.Model.Impl.DefinicionPlantillaReporteAnualProspecto2016();
            var    parametrosDocumento = plantilla.DeterminaParametrosConfiguracionDocumento(instancia);
            String claveEmisoraXBRL;

            if (!parametrosDocumento.TryGetValue("emisora", out claveEmisoraXBRL) || String.IsNullOrEmpty(claveEmisoraXBRL))
            {
                AgregarError(resultadoValidacion, null, null, "No fue posible determinar la clave de cotización de la emisora del documento.", true);
                return;
            }
            else
            {
                if (!claveEmisoraXBRL.Equals(cvePizarra, StringComparison.InvariantCultureIgnoreCase))
                {
                    LogUtil.Info("Error comparar {clavePizarra: [" + cvePizarra + "],claveCotizacionXBRL: [" + claveEmisoraXBRL + "]}");
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV007, claveEmisoraXBRL), true);
                }
            }
            //String paramfechaReporte;
            //DateTime fechaReporteXBRL;
            //if (!parametrosDocumento.TryGetValue("anio", out paramfechaReporte) ||
            //    String.IsNullOrEmpty(paramfechaReporte) ||
            //    !DateUtil.ParseDate(paramfechaReporte, (DateUtil.YMDateFormat + "T06:00:00.000Z"), out fechaReporteXBRL))
            //{
            //    AgregarError(resultadoValidacion, null, null, "No fue posible determinar el periodo del documento XBRL (" + paramfechaReporte ?? "null" + ").", true);
            //}
            //else
            //{
            //    if (fechaReporteXBRL.Year != anio)
            //    {
            //        LogUtil.Info("Error periodo {clavePizarra: [" + cvePizarra + "],fechaReporte: [" + paramfechaReporte + "], anio:[" + anio + "]}");
            //        AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RA008, anio, fechaReporteXBRL.Year), true);
            //    }
            //}

            //if (!ValidarDecimalesHechosMonetarios(instancia, DECIMALES_PERMITIDOS))
            //{
            //    AgregarError(resultadoValidacion, null, null, M_ERROR_RV011, true);
            //}
            //if (!ValidarMonedasDocumento(instancia, UNIDADES_PERMITIDAS))
            //{
            //    AgregarError(resultadoValidacion, null, null, M_ERROR_RV010, true);
            //}
        }
예제 #8
0
        /// <summary>
        /// Valida que los hechos de los roles y conceptos que requieran reportarse al acumulado actual tengan las fechas deseadas
        /// </summary>
        /// <param name="instancia">Documento de instancia a validar</param>
        /// <param name="parametros">Parametros de validación</param>
        /// <param name="fechaTrimestreParam">Fecha de trimestre que se reporta</param>
        /// <param name="resultadoValidacion">Objeto de resultado de la validación</param>
        /// <returns></returns>
        private bool ValidarHechosReportadosAlAcumulado(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, DateTime fechaTrimestreParam, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            var listaConceptosAValidar = new List <string>();

            foreach (var rol in ROL_URI_CONCEPTOS_REPORTADOS_AL_ACUMULADO)
            {
                var listaConceptosRol = UtilAbax.ObtenerListaConceptosDeRolPresentacion(instancia.Taxonomia, rol);
                foreach (var concepto in listaConceptosRol)
                {
                    listaConceptosAValidar.Add(concepto.Id);
                }
            }
            listaConceptosAValidar.AddRange(ID_CONCEPTOS_ACUMULADOS);
            DateTime fechaInicioEjercicio = new DateTime(fechaTrimestreParam.Year, 1, 1);

            foreach (var idConcepto in listaConceptosAValidar)
            {
                //Si se encuentran hechos, al menos uno debe estar reportado en el acumulado actual
                if (!ValidarAlMenosunHechoEnPeriodo(idConcepto, instancia, fechaInicioEjercicio, fechaTrimestreParam))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV012, idConcepto), true);
                    return(false);
                }
            }


            return(true);
        }
예제 #9
0
        /// <summary>
        /// Obtiene y ejecuta las validaciones específicas de acuerdo a la taxonomía del documento de instancia
        /// </summary>
        /// <param name="documentoXbrl">Documento a validar</param>
        /// <param name="parametros">Parametros extras para validación</param>
        /// <param name="resultadoValidacion">Objeto de resultado de validación</param>
        private void AplicarValidacionesDeNegocio(DocumentoInstanciaXbrlDto documentoXbrl, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            string entryPoint = null;

            foreach (var dtsDoc in documentoXbrl.DtsDocumentoInstancia)
            {
                if (dtsDoc.Tipo == DtsDocumentoInstanciaDto.SCHEMA_REF)
                {
                    entryPoint = dtsDoc.HRef;
                    break;
                }
            }
            if (entryPoint != null)
            {
                var validador = ValidadorFactory.ObtenerValidadorInstanciaXBRL(entryPoint);
                if (validador != null)
                {
                    LogUtil.Info("Se encontró validador de negocio para taxonomía:" + entryPoint);


                    validador.ValidarArchivoInstanciaXBRL(documentoXbrl, parametros, resultadoValidacion);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Procesa la carga y validación del archivo XBRL
        /// </summary>
        /// <param name="archivo">Archivo XBRL a cargar</param>
        /// <param name="resultadoValidacion">Objeto con los resultados de la validación</param>
        /// <param name="parametros">Parámetros adicionales para validación</param>
        private void ProcesarArchivoXBRL(String rutaAbsolutaArchivo, ResultadoValidacionDocumentoXBRLDto resultadoValidacion, IDictionary <string, string> parametros)
        {
            var configCarga = new ConfiguracionCargaInstanciaDto()
            {
                UrlArchivo           = rutaAbsolutaArchivo,
                CacheTaxonomia       = CacheTaxonomia,
                ConstruirTaxonomia   = true,
                EjecutarValidaciones = true,
                Errores             = new List <ErrorCargaTaxonomiaDto>(),
                ForzarCerradoDeXbrl = false,
                InfoCarga           = new AbaxCargaInfoDto()
            };
            var swTotal = Stopwatch.StartNew();
            DocumentoInstanciaXbrlDto documentoXbrl = XPEServiceImpl.GetInstance(ForzarHttp).CargarDocumentoInstanciaXbrl(configCarga);

            swTotal.Stop();

            LogUtil.Info("Tiempo de carga total (" + rutaAbsolutaArchivo + "):" + swTotal.ElapsedMilliseconds);

            resultadoValidacion.Valido           = true;
            resultadoValidacion.MsCarga          = configCarga.InfoCarga.MsCarga;
            resultadoValidacion.MsValidacion     = configCarga.InfoCarga.MsValidacion;
            resultadoValidacion.MsFormulas       = configCarga.InfoCarga.MsFormulas;
            resultadoValidacion.MsTransformacion = configCarga.InfoCarga.MsTransformacion;
            //El documento es legible, organizar periodos
            if (documentoXbrl != null)
            {
                if (documentoXbrl.Taxonomia == null)
                {
                    documentoXbrl.Taxonomia = AgregarTaxonomiaACache(documentoXbrl.DtsDocumentoInstancia, CacheTaxonomia);
                }

                AplicarValidacionesGenerales(documentoXbrl, parametros, resultadoValidacion);

                if (resultadoValidacion.Valido)
                {
                    CrearResumenDePeriodos(documentoXbrl, resultadoValidacion);
                    //Aplicar validaciones específicas
                    AplicarValidacionesDeNegocio(documentoXbrl, parametros, resultadoValidacion);
                }
                documentoXbrl.Cerrar();
                documentoXbrl = null;
                //System.GC.Collect();
            }

            //Acomodar errores
            foreach (var error in configCarga.Errores)
            {
                if (error.IdContexto == null)
                {
                    resultadoValidacion.ErroresGenerales.Add(error);
                }
                else
                {
                    if (resultadoValidacion.Periodos.Any(x => x.IdContextos.Contains(error.IdContexto)))
                    {
                        resultadoValidacion.Periodos.First(x => x.IdContextos.Contains(error.IdContexto)).Errores.Add(error);
                    }
                }
                resultadoValidacion.Valido = false;
            }
        }
예제 #11
0
        public override ResultadoOperacionDto ValidarDocumentoInstanciaXBRL(Stream archivo, String rutaAbsolutaArchivo, String nombreArchivo, IDictionary <string, string> parametros)
        {
            LogUtil.Info("Entrando al servicio de validación");
            var resultadoOp         = new ResultadoOperacionDto();
            var resultadoValidacion = new ResultadoValidacionDocumentoXBRLDto();

            resultadoValidacion.ErroresGenerales = new List <ErrorCargaTaxonomiaDto>();
            resultadoValidacion.Periodos         = new List <ResumenValidacionPeriodoXBRLDto>();
            resultadoOp.InformacionExtra         = resultadoValidacion;
            var xbrlService = XPEServiceImpl.GetInstance(ForzarHttp);

            if (xbrlService.GetErroresInicializacion() != null && xbrlService.GetErroresInicializacion().Count > 0)
            {
                resultadoValidacion.Valido = false;
                foreach (var errorInicializacion in xbrlService.GetErroresInicializacion())
                {
                    resultadoValidacion.ErroresGenerales.Add(errorInicializacion);
                }
                resultadoOp.Resultado = false;
                return(resultadoOp);
            }


            if (nombreArchivo.ToLower().EndsWith(CommonConstants.ExtensionXBRL))
            {
                ProcesarArchivoXBRL(rutaAbsolutaArchivo, resultadoValidacion, parametros);
            }
            else if (nombreArchivo.ToLower().EndsWith(CommonConstants.ExtensionZIP))
            {
                ProcesarArchivoZip(rutaAbsolutaArchivo, resultadoValidacion, parametros);
            }
            else
            {
                AgregarErrorFatal(resultadoValidacion, null, null, null, "El archivo a validar debe tener extensión ZIP o XBRL");
            }

            resultadoOp.InformacionAuditoria = new InformacionAuditoriaDto
            {
                Accion =
                    ConstantsAccionAuditable.Validar,
                Empresa   = null,
                Fecha     = DateTime.Now,
                IdUsuario = null,
                Modulo    = ConstantsModulo.ServicioValidacionDocumentosXBRL,
                Registro  =
                    "Validación de documento de instancia:  " +
                    nombreArchivo
            };
            resultadoOp.Resultado = resultadoValidacion.Valido;

            if (maxErrors == -1)
            {
                try
                {
                    var bdMaxErrors = ParametroSistemaService.ObtenerValorParametroSistema(ConstantsParametrosSistema.MAX_ERROR_VALIDAR_XBRL, "0");
                    int tempMaxErrors;
                    if (Int32.TryParse(bdMaxErrors, out tempMaxErrors))
                    {
                        maxErrors = tempMaxErrors;
                    }
                }
                catch (Exception e)
                {
                    LogUtil.Error(e);
                    maxErrors = 0;
                }
            }
            if (maxErrors < 0)
            {
                maxErrors = 0;
            }
            //Aplicar la configuración de errores máximos
            if (maxErrors > 0)
            {
                int erroresRestantes = maxErrors;
                //Empezar por los errores generales
                if (resultadoValidacion.ErroresGenerales != null && resultadoValidacion.ErroresGenerales.Count > maxErrors)
                {
                    resultadoValidacion.ErroresGenerales = resultadoValidacion.ErroresGenerales.Take(maxErrors).ToList();
                    erroresRestantes = 0;
                }

                if (resultadoValidacion.Periodos != null)
                {
                    foreach (var periodo in resultadoValidacion.Periodos)
                    {
                        if (periodo.Errores != null)
                        {
                            if (periodo.Errores.Count > erroresRestantes)
                            {
                                periodo.Errores = periodo.Errores.Take(erroresRestantes).ToList();
                            }
                            erroresRestantes -= periodo.Errores.Count;
                        }
                    }
                }
            }

            return(resultadoOp);
        }
        /// <summary>
        /// Aplica las reglas de validacion de periodos de acuerdo a lo requerido:
        /// Se valida que exista por lo menos la acumulada del ejercicio reportado
        /// para los formatos principales de la taxonomía
        /// </summary>
        /// <param name="instancia">Documento de instancia a validar</param>
        /// <param name="parametros">Parametros de validación</param>
        /// <param name="fechaTrimestreParam">Fecha de trimestre reportado</param>
        /// <param name="hrefTax">Dirección HREF de la taxonomía referenciada</param>
        /// <param name="resultadoValidacion">Objeto de resultado de validación</param>
        /// <returns>True si la validación es exitosa, false si falta algún dato requerido, si faltan datos requeridos se agregan los mensajes de error correspondientes</returns>
        private bool ValidarPeriodosRequeridos(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, DateTime fechaTrimestreParam, String hrefTax, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            DateTime fechaInicioEjercicio = new DateTime(fechaTrimestreParam.Year, 1, 1);
            DateTime fechaInicioTrimestre = new DateTime(fechaTrimestreParam.Ticks).AddDays(1).AddMonths(-3);

            //Estado de situación financiera: Existencia del cierre del trimestre
            if (!ExisteInformacionEnPeriodo(instancia, ID_EQUITY_AND_LIABILITES, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de resultados:
            //Trimestral
            if (!ExisteInformacionEnPeriodo(instancia, ID_UTILIDAD_PERDIDA_NETA, fechaInicioTrimestre, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioTrimestre) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }
            //Acumulado
            if (!ExisteInformacionEnPeriodo(instancia, ID_UTILIDAD_PERDIDA_NETA, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de resultados ORI:
            //Trimestral
            if (!ExisteInformacionEnPeriodo(instancia, ID_RESULTADO_INTEGRAL, fechaInicioTrimestre, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioTrimestre) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }
            //Acumulado
            if (!ExisteInformacionEnPeriodo(instancia, ID_RESULTADO_INTEGRAL, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de flujos de efectivo
            if (!ExisteInformacionEnPeriodo(instancia, ID_CONCEPTO_INCREMENTO_DISMINUCION_EFECTIVO_ANTES_DE_CAMBIO_EN_TASA, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de cambios en el capital contable
            //Para cada miembro, empezando por la dim default

            /* Reactiva eventualmente esta validación
             * if (!ExisteInformacionEnPeriodo(instancia, ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, new List<DimensionInfoDto>()))
             * {
             *  AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
             *  return false;
             * }
             * if (!ExisteInformacionEnPeriodo(instancia, ID_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, new List<DimensionInfoDto>()))
             * {
             *  AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaTrimestreParam)), false);
             *  return false;
             * }
             */
            var listaDimCapital  = new List <DimensionInfoDto>();
            var dimensionBuscada = new DimensionInfoDto()
            {
                IdDimension = ID_COMPONENTES_DEL_CAPITAL,
                Explicita   = true
            };

            listaDimCapital.Add(dimensionBuscada);

            foreach (var idMiembroCapital in MIEMBROS_CAPITAL[hrefTax])
            {
                dimensionBuscada.IdItemMiembro = idMiembroCapital;
                if (!ExisteInformacionEnPeriodo(instancia, ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, listaDimCapital))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                    return(false);
                }
                if (!ExisteInformacionEnPeriodo(instancia, ID_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, listaDimCapital))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV013, DateUtil.ToStandarString(fechaTrimestreParam)), false);
                    return(false);
                }
            }


            return(true);
        }
        public override void ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            LogUtil.Info("Validando reglas FIDECOMISOS 2015 para:" + instancia.NombreArchivo);
            string hrefTax = null;

            foreach (var dts in instancia.DtsDocumentoInstancia)
            {
                if (dts.Tipo == DtsDocumentoInstanciaDto.SCHEMA_REF)
                {
                    hrefTax = dts.HRef;
                    break;
                }
            }
            if (hrefTax == null)
            {
                throw new Exception("Documento de instancia sin DTS de tipo HREF");
            }
            if (!PREFIJOS_TAXONOMIAS.ContainsKey(hrefTax))
            {
                throw new Exception("Documento de instancia a validar no corresponde a ninguna taxonomía de Fideicomisos BMV 2015");
            }
            var prefijoIdConceptos = PREFIJOS_TAXONOMIAS[hrefTax];


            //La clave del fideicomitente reportada en el documento de instancia debe ser la misma clave del fide (clave de fideicomitente) enviada como parámetro
            String cvePizarra = parametros.ContainsKey(CVE_FIDEICOMITENTE) ? parametros[CVE_FIDEICOMITENTE] : null;

            if (cvePizarra == null)
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, CVE_FIDEICOMITENTE), true);
                LogUtil.Info("claveFideicomientente: " + cvePizarra);
                return;
            }

            //Buscar alias de la clave de pizarra
            var aliasClaveCotizacion = obtenerAliasEmpresa(cvePizarra);

            if (aliasClaveCotizacion != null)
            {
                cvePizarra = aliasClaveCotizacion;
                LogUtil.Info("alias: " + cvePizarra);
            }

            string claveCotizacionXBRL = ObtenerValorNoNumerico(prefijoIdConceptos + NOMBRE_CONCEPTO_FIDEICOMITENTE, instancia);

            if (claveCotizacionXBRL != null && !claveCotizacionXBRL.Equals(cvePizarra, StringComparison.InvariantCultureIgnoreCase))
            {
                LogUtil.Info("Error comparar {clavePizarra: [" + cvePizarra + "],claveCotizacionXBRL: [" + claveCotizacionXBRL + "]}");
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV011, claveCotizacionXBRL), true);
                return;
            }
            //El dato dentro del archivo “Fecha de cierre del periodo sobre el que se informa”  debe de coincidir con la fecha del trimestre a reportar enviada como parámetro.
            String strFechaTrimestre = parametros.ContainsKey(FECHA_TRIMESTRE) ? parametros[FECHA_TRIMESTRE] : null;

            if (strFechaTrimestre == null)
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, FECHA_TRIMESTRE), true);
                return;
            }
            DateTime fechaTrimestreParam = DateTime.MinValue;

            if (!XmlUtil.ParsearUnionDateTime(strFechaTrimestre, out fechaTrimestreParam))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FORMATO_PARAMETRO, FECHA_TRIMESTRE, strFechaTrimestre), true);
                return;
            }
            var fechaTrimestreXbrl = ObtenerValorFecha(ID_FECHA_CIERRE_REPORTE_2014, instancia);

            if (!fechaTrimestreXbrl.Equals(DateTime.MinValue))
            {
                if (!fechaTrimestreXbrl.Equals(fechaTrimestreParam))
                {
                    AgregarError(resultadoValidacion, null, null, M_ERROR_FID_RV012, true);
                    return;
                }
            }

            if (!ValidarPeriodosRequeridos(instancia, parametros, fechaTrimestreParam, hrefTax, resultadoValidacion))
            {
                return;
            }
            if (!ValidarMonedasDocumento(instancia, UNIDADES_PERMITIDAS))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV014), true);
                return;
            }

            if (!ValidarDecimalesHechosMonetarios(instancia, DECIMALES_PERMITIDOS))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV015), true);
                return;
            }
            if (!ValidarHechosReportadosAlAcumulado(instancia, hrefTax, fechaTrimestreParam, resultadoValidacion))
            {
                return;
            }
        }
예제 #14
0
        public override void  ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            LogUtil.Info("Validando reglas IFRS 2015 para:" + instancia.NombreArchivo);

            //La clave de la emisora reportada en el documento de instancia debe ser la misma clave de emisora (clave de pizarra) enviada como parámetro
            //2016-03-25 Para fibras, caso específico, se tomará en cuenta, si existe, la cveFideicomitente
            String cvePizarra = null;

            if (parametros.ContainsKey(CVE_FIDEICOMITENTE) && !String.IsNullOrEmpty(parametros[CVE_FIDEICOMITENTE]))
            {
                cvePizarra = parametros[CVE_FIDEICOMITENTE];
                LogUtil.Info("claveFideicomientente: " + cvePizarra);
            }
            if (cvePizarra == null)
            {
                cvePizarra = parametros.ContainsKey(CVE_PIZARRA) ? parametros[CVE_PIZARRA] : null;
                LogUtil.Info("clavePizarra: " + cvePizarra);
            }

            if (cvePizarra == null)
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, CVE_PIZARRA), true);
                return;
            }

            //Buscar alias de la clave de pizarra
            var aliasClaveCotizacion = obtenerAliasEmpresa(cvePizarra);

            if (aliasClaveCotizacion != null)
            {
                cvePizarra = aliasClaveCotizacion;
                LogUtil.Info("alias: " + cvePizarra);
            }

            string claveCotizacionXBRL = ObtenerValorNoNumerico(ID_CLAVE_COTIZACION_2014, instancia);

            if (claveCotizacionXBRL != null && !claveCotizacionXBRL.Equals(cvePizarra, StringComparison.InvariantCultureIgnoreCase))
            {
                LogUtil.Info("Error comparar {clavePizarra: [" + cvePizarra + "],claveCotizacionXBRL: [" + claveCotizacionXBRL + "]}");
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV007, claveCotizacionXBRL), true);
                return;
            }
            //El dato dentro del archivo “Fecha de cierre del periodo sobre el que se informa”  debe de coincidir con la fecha del trimestre a reportar enviada como parámetro.
            String strFechaTrimestre = parametros.ContainsKey(FECHA_TRIMESTRE) ? parametros[FECHA_TRIMESTRE] : null;

            if (strFechaTrimestre == null)
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, FECHA_TRIMESTRE), true);
                return;
            }
            DateTime fechaTrimestreParam = DateTime.MinValue;

            if (!XmlUtil.ParsearUnionDateTime(strFechaTrimestre, out fechaTrimestreParam))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FORMATO_PARAMETRO, FECHA_TRIMESTRE, strFechaTrimestre), true);
                return;
            }
            var fechaTrimestreXbrl = ObtenerValorFecha(ID_FECHA_CIERRE_REPORTE_2014, instancia);

            if (!fechaTrimestreXbrl.Equals(DateTime.MinValue))
            {
                if (!fechaTrimestreXbrl.Equals(fechaTrimestreParam))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV008, fechaTrimestreXbrl, fechaTrimestreParam), true);
                    return;
                }
            }

            if (!ValidarPeriodosRequeridos(instancia, parametros, fechaTrimestreParam, resultadoValidacion))
            {
                return;
            }

            if (!ValidarHechosReportadosAlAcumulado(instancia, parametros, fechaTrimestreParam, resultadoValidacion))
            {
                return;
            }

            if (!ValidarMonedasDocumento(instancia, UNIDADES_PERMITIDAS))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV010), true);
                return;
            }

            if (!ValidarDecimalesHechosMonetarios(instancia, DECIMALES_PERMITIDOS))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV011), true);
                return;
            }

            if (!ValidarCuentasExtras(instancia, parametros, fechaTrimestreParam, resultadoValidacion))
            {
                return;
            }
        }
예제 #15
0
 /// <summary>
 /// Realiza validaciones generales respecto al formato del archivo
 /// </summary>
 /// <param name="streamArchivo"></param>
 /// <param name="documentoXbrl"></param>
 /// <param name="parametros"></param>
 /// <param name="resultadoValidcion"></param>
 private void AplicarValidacionesGenerales(DocumentoInstanciaXbrlDto documentoXbrl, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
 {
     ValidarCodificacion(null, documentoXbrl, parametros, resultadoValidacion);
     if (resultadoValidacion.Valido)
     {
         ValidarTaxonomiaConocida(documentoXbrl, parametros, resultadoValidacion);
     }
 }
예제 #16
0
        /// <summary>
        /// Valida las operaciones extras sobre cuentas específicas del documento de instancia:
        /// Validaciones de consolidado = true :
        /// Utilidad (pérdida) neta = Utilidad (pérdida) atribuible a la participación controladora + Utilidad (pérdida) atribuible a la participación no controladora
        /// Resultado integral =resultado integral de la participación controladora + resultado integral de la participación no controladora
        /// Validaciones generales
        /// Incremento (disminución) neto de efectivo y equivalentes de efectivo + Efectivo y equivalentes de efectivo al principio del periodo = Efectivo y equivalentes de efectivo al final del periodo
        /// </summary>
        /// <param name="instancia">Documento de instancia a validar</param>
        /// <param name="parametros">Parametros extras para validación</param>
        /// <param name="fechaTrimestreParam">Fecha de cierre de trimestre del reporte</param>
        /// <param name="resultadoValidacion">Objeto del resultado de la validación</param>
        /// <returns></returns>
        private bool ValidarCuentasExtras(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, DateTime fechaTrimestreParam, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            var strConsolidado = ObtenerValorNoNumerico(ID_CUENTA_CONSOLIDADO, instancia);

            if (strConsolidado != null && CommonConstants.CADENAS_VERDADERAS.Any(x => x.Equals(strConsolidado, StringComparison.InvariantCultureIgnoreCase)))
            {
                //Validaciones para Consolidado = si

                //Utilidad (pérdida) neta = Utilidad (pérdida) atribuible a la participación controladora + Utilidad (pérdida) atribuible a la participación no controladora
                if (instancia.HechosPorIdConcepto.ContainsKey(ID_UTILIDAD_PERDIDA_NETA))
                {
                    var dimensiones = new List <DimensionInfoDto>();
                    foreach (var idHechoutilidadPerdidaNeta in instancia.HechosPorIdConcepto[ID_UTILIDAD_PERDIDA_NETA])
                    {
                        if (instancia.HechosPorId.ContainsKey(idHechoutilidadPerdidaNeta))
                        {
                            var utilidadPerdidaNeta = instancia.HechosPorId[idHechoutilidadPerdidaNeta];
                            var ctx = instancia.ContextosPorId[utilidadPerdidaNeta.IdContexto];
                            if (!ctx.ContieneInformacionDimensional)
                            {
                                var utilidadPerdidaNetaControladora   = instancia.BuscarHechos(ID_UTILIDAD_PERDIDA_NETA_PARTICIPANCION_CONTROLADORA, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                                var utilidadPerdidaNetaNoControladora = instancia.BuscarHechos(ID_UTILIDAD_PERDIDA_NETA_PARTICIPANCION_NO_CONTROLADORA, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                                if (utilidadPerdidaNetaControladora.Count > 0 && utilidadPerdidaNetaNoControladora.Count > 0)
                                {
                                    if (utilidadPerdidaNeta.ValorNumerico != utilidadPerdidaNetaControladora[0].ValorNumerico + utilidadPerdidaNetaNoControladora[0].ValorNumerico)
                                    {
                                        AgregarError(resultadoValidacion, null, ctx.Id,
                                                     String.Format(M_ERROR_RV013, utilidadPerdidaNeta.ValorNumerico, utilidadPerdidaNetaControladora[0].ValorNumerico, utilidadPerdidaNetaNoControladora[0].ValorNumerico), true);
                                        return(false);
                                    }
                                }
                            }
                        }
                    }
                }

                //Resultado integral =resultado integral de la participación controladora + resultado integral de la participación no controladora
                if (instancia.HechosPorIdConcepto.ContainsKey(ID_RESULTADO_INTEGRAL))
                {
                    var dimensiones = new List <DimensionInfoDto>();
                    foreach (var idHechoResultadoIntegral in instancia.HechosPorIdConcepto[ID_RESULTADO_INTEGRAL])
                    {
                        if (instancia.HechosPorId.ContainsKey(idHechoResultadoIntegral))
                        {
                            var resultadoIntegral = instancia.HechosPorId[idHechoResultadoIntegral];
                            var ctx = instancia.ContextosPorId[resultadoIntegral.IdContexto];
                            if (!ctx.ContieneInformacionDimensional)
                            {
                                var resultadoIntegralControladora   = instancia.BuscarHechos(ID_RESULTADO_INTEGRAL_CONTROLADORA, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                                var resultadoIntegralNoControladora = instancia.BuscarHechos(ID_RESULTADO_INTEGRAL_NO_CONTROLADORA, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                                if (resultadoIntegralControladora.Count > 0 && resultadoIntegralNoControladora.Count > 0)
                                {
                                    if (resultadoIntegral.ValorNumerico != resultadoIntegralControladora[0].ValorNumerico + resultadoIntegralNoControladora[0].ValorNumerico)
                                    {
                                        AgregarError(resultadoValidacion, null, ctx.Id,
                                                     String.Format(M_ERROR_RV014, resultadoIntegral.ValorNumerico, resultadoIntegralControladora[0].ValorNumerico, resultadoIntegralNoControladora[0].ValorNumerico), true);
                                        return(false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //Incremento (disminución) neto de efectivo y equivalentes de efectivo + Efectivo y equivalentes de efectivo al principio del periodo = Efectivo y equivalentes de efectivo al final del periodo
            if (instancia.HechosPorIdConcepto.ContainsKey(ID_INCREMENTO_DISMINUCION_EFECTIVO_Y_EQUIVALENTES))
            {
                var dimensiones = new List <DimensionInfoDto>();
                foreach (var idHechoIncrementoDisminucion in instancia.HechosPorIdConcepto[ID_INCREMENTO_DISMINUCION_EFECTIVO_Y_EQUIVALENTES])
                {
                    if (instancia.HechosPorId.ContainsKey(idHechoIncrementoDisminucion))
                    {
                        var incrementoDisminucion = instancia.HechosPorId[idHechoIncrementoDisminucion];
                        var ctx = instancia.ContextosPorId[incrementoDisminucion.IdContexto];
                        if (!ctx.ContieneInformacionDimensional)
                        {
                            var efectivoAlInicio = instancia.BuscarHechos(ID_EFECTIVO_Y_EQUIVALENTES, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaInicio.AddDays(-1), dimensiones, true);
                            var efectivoAlFinal  = instancia.BuscarHechos(ID_EFECTIVO_Y_EQUIVALENTES, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                            if (efectivoAlInicio.Count > 0 && efectivoAlFinal.Count > 0)
                            {
                                if (incrementoDisminucion.ValorNumerico != efectivoAlFinal[0].ValorNumerico - efectivoAlInicio[0].ValorNumerico)
                                {
                                    AgregarError(resultadoValidacion, null, ctx.Id,
                                                 String.Format(M_ERROR_RV015, efectivoAlFinal[0].ValorNumerico, efectivoAlInicio[0].ValorNumerico, incrementoDisminucion.ValorNumerico), true);
                                    return(false);
                                }
                            }
                        }
                    }
                }
            }

            //El valor de Capital contable al final del periodo  debe ser igual a la suma de Capital contable al principio del periodo  + Total Incremento (disminuci\u00F3n) en el capital contable  para el miembro de dominio
            if (instancia.HechosPorIdConcepto.ContainsKey(ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE))
            {
                var dimensiones = new List <DimensionInfoDto>();
                foreach (var idHechosCambiosEnCapital in instancia.HechosPorIdConcepto[ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE])
                {
                    if (instancia.HechosPorId.ContainsKey(idHechosCambiosEnCapital))
                    {
                        var cambiosCapital = instancia.HechosPorId[idHechosCambiosEnCapital];
                        var ctx            = instancia.ContextosPorId[cambiosCapital.IdContexto];
                        dimensiones.Clear();
                        if (ctx.ValoresDimension != null)
                        {
                            dimensiones.AddRange(ctx.ValoresDimension);
                        }
                        var capitalInicial = instancia.BuscarHechos(ID_CAPITAL_CONTABLE, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaInicio.AddDays(-1), dimensiones, true);
                        var capitalFinal   = instancia.BuscarHechos(ID_CAPITAL_CONTABLE, null, null, ctx.Periodo.FechaInicio, ctx.Periodo.FechaFin, dimensiones, true);
                        if (capitalInicial.Count > 0 && capitalFinal.Count > 0)
                        {
                            if (cambiosCapital.ValorNumerico != capitalFinal[0].ValorNumerico - capitalInicial[0].ValorNumerico)
                            {
                                AgregarError(resultadoValidacion, null, ctx.Id,
                                             String.Format(M_ERROR_RV016, capitalFinal[0].ValorNumerico, capitalInicial[0].ValorNumerico, cambiosCapital.ValorNumerico), true);
                                return(false);
                            }
                        }
                    }
                }
            }


            return(true);
        }
예제 #17
0
        /// <summary>
        /// Valida que la taxonomía a la que pertenece el documento de instancia sea una taxonía válida y conocida
        /// de acuerdo al catálog de taxonomías
        /// </summary>
        /// <param name="documentoXbrl">Documento XBRL a validar</param>
        /// <param name="parametros">Parametros utilizados durante la validación</param>
        /// <param name="resultadoValidacion">Objeto de resultado de la validación</param>
        private void ValidarTaxonomiaConocida(DocumentoInstanciaXbrlDto documentoXbrl, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            long   idEmpresa  = 0;
            string cveEmpresa = null;

            if (parametros.ContainsKey("cveFideicomitente") && !string.IsNullOrEmpty(parametros["cveFideicomitente"]))
            {
                cveEmpresa = parametros["cveFideicomitente"];
            }
            if (cveEmpresa == null && parametros.ContainsKey("cvePizarra"))
            {
                cveEmpresa = parametros["cvePizarra"];
            }
            string esProspectoParam = String.Empty;

            parametros.TryGetValue("esProspecto", out esProspectoParam);
            bool esProspecto = !String.IsNullOrEmpty(esProspectoParam) && esProspectoParam.ToLower().Trim().Equals("true");

            LogUtil.Info("esProspectoParam: [" + esProspectoParam + "]");

            if (cveEmpresa == null)
            {
                AgregarErrorFatal(resultadoValidacion, null, null, null, "Faltan parámetros de invocación: cvePizarra o cveFideicomitente");
                return;
            }
            var emp = EmpresaRepository.GetQueryable().Where(x => x.NombreCorto == cveEmpresa).FirstOrDefault();

            if (emp == null)
            {
                //Buscar por alias
                emp = EmpresaRepository.GetQueryable().Where(x => x.AliasClaveCotizacion == cveEmpresa).FirstOrDefault();
            }
            if (emp != null)
            {
                if (documentoXbrl.DtsDocumentoInstancia != null && documentoXbrl.DtsDocumentoInstancia.Count > 0)
                {
                    var href = documentoXbrl.DtsDocumentoInstancia[0].HRef ?? String.Empty;
                    href = href.ToLower().Trim();
                    if (esProspecto && !ValidaTaxonomiaProspecto(href))
                    {
                        AgregarErrorFatal(resultadoValidacion, null, null, null, "Para este tramite se debe utilizar una taxonomías de prospecto.");
                        LogUtil.Error("Se intento envíar un documento de tipo prospecto para una taxonomía no asignada {IdEmpresa:[" + emp.IdEmpresa + "], cveEmpresa:[" + cveEmpresa + "] Href:[" + href + "]}");
                    }
                    if (!esProspecto && ValidaTaxonomiaProspecto(href))
                    {
                        AgregarErrorFatal(resultadoValidacion, null, null, null, "Las taxonomías de prospecto deben reportarse desde el tramite correspondiente de Stiv.");
                        LogUtil.Error("Se intento envíar un documento de tipo prospecto no indicado como prospecto {IdEmpresa:[" + emp.IdEmpresa + "], cveEmpresa:[" + cveEmpresa + "] Href:[" + href + "]}");
                    }
                    if (!EmpresaRepository.ExisteTaxonomiaParaTipoEmpresaDeEmpresa(emp.IdEmpresa, href))
                    {
                        AgregarErrorFatal(resultadoValidacion, null, null, null, "La taxonomía del archivo de instancia no es la correcta para el tipo de envío.");
                        LogUtil.Error("Se intento envíar un documento de una taxonomía no asignada {IdEmpresa:[" + emp.IdEmpresa + "], cveEmpresa:[" + cveEmpresa + "] Href:[" + href + "]}");
                    }
                }
                else
                {
                    AgregarErrorFatal(resultadoValidacion, null, null, null, "La taxonomía del archivo de instancia no es la correcta para el tipo de envío. (No existe schemaRef)");
                }
            }
            else
            {
                AgregarErrorFatal(resultadoValidacion, null, null, null, "No se encontró empresa con clave:" + cveEmpresa);
            }
        }
예제 #18
0
        /// <summary>
        /// Aplica las reglas de validacion de periodos de acuerdo a lo requerido:
        /// Se valida que exista por lo menos la información trimestral y acumulada del ejercicio reportado
        /// para los formatos principales de la taxonomía
        /// </summary>
        /// <param name="instancia">Documento de instancia a validar</param>
        /// <param name="parametros">Parametros de validación</param>
        /// <param name="fechaTrimestreParam">Fecha de trimestre reportado</param>
        /// <param name="resultadoValidacion">Objeto de resultado de validación</param>
        /// <returns>True si la validación es exitosa, false si falta algún dato requerido, si faltan datos requeridos se agregan los mensajes de error correspondientes</returns>
        private bool ValidarPeriodosRequeridos(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, DateTime fechaTrimestreParam, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            DateTime fechaInicioEjercicio = new DateTime(fechaTrimestreParam.Year, 1, 1);
            DateTime fechaInicioTrimestre = new DateTime(fechaTrimestreParam.Ticks).AddDays(1).AddMonths(-3);
            DateTime fechaA12Meses        = new DateTime(fechaTrimestreParam.Ticks).AddDays(1).AddYears(-1);

            LogUtil.Info("FechaInicioEjercicio:" + DateUtil.ToStandarString(fechaInicioEjercicio));
            LogUtil.Info("FechaInicioTrimestre:" + DateUtil.ToStandarString(fechaInicioTrimestre));
            //Estado de situación financiera: Exitencia del cierre del trimestre
            if (!ExisteInformacionEnPeriodo(instancia, ID_ACTIVOS, fechaInicioTrimestre, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de resultados:
            //Trimestral
            if (!ExisteInformacionEnPeriodo(instancia, ID_UTILIDAD_PERDIDA_NETA, fechaInicioTrimestre, fechaTrimestreParam, null) || !ExisteInformacionEnPeriodo(instancia, ID_RESULTADO_INTEGRAL, fechaInicioTrimestre, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaInicioTrimestre) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Acumulado
            if (!ExisteInformacionEnPeriodo(instancia, ID_UTILIDAD_PERDIDA_NETA, fechaInicioEjercicio, fechaTrimestreParam, null) || !ExisteInformacionEnPeriodo(instancia, ID_RESULTADO_INTEGRAL, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Informativos a 12 meses

            /*if (!ExisteInformacionEnPeriodo(instancia, ID_UTILIDAD_PERDIDA_NETA, fechaA12Meses, fechaTrimestreParam, null))
             * {
             *  AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaA12Meses) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
             *  return false;
             * }*/

            //Estado de flujos de efectivo
            if (!ExisteInformacionEnPeriodo(instancia, ID_INCREMENTO_DISMINUCION_EFECTIVO_Y_EQUIVALENTES, fechaInicioEjercicio, fechaTrimestreParam, null))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            //Estado de cambios en el capital contable
            //Para cada miembro, empezando por la dim default

            /* Temporalmente ignorar la dimension defaul
             * if (!ExisteInformacionEnPeriodo(instancia, ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, new List<DimensionInfoDto>()))
             * {
             *  AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
             *  return false;
             * }
             */
            if (!ExisteInformacionEnPeriodo(instancia, ID_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, new List <DimensionInfoDto>()))
            {
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaTrimestreParam)), false);
                return(false);
            }

            var listaDimCapital  = new List <DimensionInfoDto>();
            var dimensionBuscada = new DimensionInfoDto()
            {
                IdDimension = ID_COMPONENTES_DEL_CAPITAL,
                Explicita   = true
            };

            listaDimCapital.Add(dimensionBuscada);

            foreach (var idMiembroCapital in ID_MIEMBROS_CAPITAL_CONTABLE)
            {
                dimensionBuscada.IdItemMiembro = idMiembroCapital;
                if (!ExisteInformacionEnPeriodo(instancia, ID_CAMBIOS_EN_EL_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, listaDimCapital))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaInicioEjercicio) + " - " + DateUtil.ToStandarString(fechaTrimestreParam)), false);
                    return(false);
                }
                if (!ExisteInformacionEnPeriodo(instancia, ID_CAPITAL_CONTABLE, fechaInicioEjercicio, fechaTrimestreParam, listaDimCapital))
                {
                    AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_RV009, DateUtil.ToStandarString(fechaTrimestreParam)), false);
                    return(false);
                }
            }


            return(true);
        }
        public override void ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion)
        {
            LogUtil.Info("Validando reglas Eventos Relevantes para:" + instancia.NombreArchivo);
            string hrefTax = null;

            foreach (var dts in instancia.DtsDocumentoInstancia)
            {
                if (dts.Tipo == DtsDocumentoInstanciaDto.SCHEMA_REF)
                {
                    hrefTax = dts.HRef;
                    break;
                }
            }
            if (hrefTax == null)
            {
                throw new Exception("Documento de instancia sin DTS de tipo HREF");
            }
            if (!ESPACIOS_NOMBRE.ContainsKey(hrefTax))
            {
                throw new Exception("Documento de instancia a validar no corresponde a ninguna taxonomía de Eventos relevantes");
            }
            var prefijoIdConceptos = ESPACIOS_NOMBRE[hrefTax];


            //La clave del fideicomitente reportada en el documento de instancia debe ser la misma clave del fide (clave de fideicomitente) enviada como parámetro
            String cvePizarra = parametros.ContainsKey(PARAMETRO_CLAVE_PIZARRRA) ? parametros[PARAMETRO_CLAVE_PIZARRRA] : null;

            if (cvePizarra == null)
            {
                AgregarError(resultadoValidacion, null, null, String.Format(MSG_ERROR_FALTA_PARAMETRO, PARAMETRO_CLAVE_PIZARRRA), true);
                LogUtil.Info("clavePizarra: " + cvePizarra);
                return;
            }

            String claveFideicomitente = null;

            if (parametros.TryGetValue(CVE_FIDEICOMITENTE, out claveFideicomitente) && !String.IsNullOrEmpty(claveFideicomitente))
            {
                LogUtil.Info("{clavePizarra:[" + cvePizarra + "] ,claveFideicomientente: [" + claveFideicomitente + "]}");
                cvePizarra = claveFideicomitente;
            }

            //Buscar alias de la clave de pizarra
            var aliasClaveCotizacion = obtenerAliasEmpresa(cvePizarra);

            if (aliasClaveCotizacion != null)
            {
                cvePizarra = aliasClaveCotizacion;
                LogUtil.Info("alias: " + cvePizarra);
            }

            string claveCotizacionXBRL = ObtenerValorNoNumerico(prefijoIdConceptos + NOMBRE_CONCEPTO_FIDEICOMITENTE, instancia);

            if (claveCotizacionXBRL != null && !claveCotizacionXBRL.Equals(cvePizarra, StringComparison.InvariantCultureIgnoreCase))
            {
                LogUtil.Info("Error comparar {clavePizarra: [" + cvePizarra + "],claveCotizacionXBRL: [" + claveCotizacionXBRL + "]}");
                AgregarError(resultadoValidacion, null, null, String.Format(M_ERROR_FID_RV011, claveCotizacionXBRL), true);
                return;
            }
        }