/// <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); } } }
/// <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); }
/// <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; } } }
public abstract void ValidarArchivoInstanciaXBRL(DocumentoInstanciaXbrlDto instancia, IDictionary <string, string> parametros, ResultadoValidacionDocumentoXBRLDto resultadoValidacion);
/// <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(); }
/// <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"); } } }
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); //} }
/// <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); }
/// <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); } } }
/// <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; } }
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; } }
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; } }
/// <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); } }
/// <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); }
/// <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); } }
/// <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; } }