private async Task <bool> Calcular_categorias_nivel_n(List <Categoria> categoriasz, List <Periodo> periodos, int nivelaOperar) { //controladores IndicadorsController controlIndicadores = new IndicadorsController(db, userManager); EjecucionsController controlEjecucion = new EjecucionsController(db, userManager); PeriodosController controlPeriodos = new PeriodosController(db, userManager); CategoriasController controlCategorias = new CategoriasController(db, userManager); EjecucionCategoriaController controlEjecucionCategoria = new EjecucionCategoriaController(db, userManager); // variables List <Indicador> indicadores = new List <Indicador>(); List <Ejecucion> ejecuciones = new List <Ejecucion>(); List <EjecucionCalculada> ejecucionesCalculadas = new List <EjecucionCalculada>(); //List<Periodo> periodos = controlPeriodos.getAll(); foreach (Categoria categoriax in categoriasz) { List <Categoria> CategoriasPAraIndicadores = await controlCategorias.GetFomNivelAndParent(categoriax.id, nivelaOperar); indicadores = await controlIndicadores.getFromCategorias(CategoriasPAraIndicadores); List <EjecucionCalculada> listadoEjecuciones = new List <EjecucionCalculada>(); List <EjecucionCategoria> respuestas = new List <EjecucionCategoria>(); foreach (Indicador indicador in indicadores) { //-------------- generacion de un objeto genérico para manejar los diferentes tipos de indicadores ObjectHandle manejador = Activator.CreateInstance(null, "seguimiento.Formulas." + indicador.TipoIndicador.file); //se crea un manejador op -objeto generico- y un operador generico que permite llamar a las formulas con la cadena del tipo de indiciador: mantenimiento, incremento etc Object op = manejador.Unwrap(); Type t = op.GetType(); MethodInfo operadorPeriodo = t.GetMethod("Calculo_periodo"); //operador es un metodo generico que refleja la funcionalidad de Calculo periodo MethodInfo operadorSubtotal = t.GetMethod("Calculo_subtotal"); //operador es un metodo generico que refleja la funcionalidad de Calculo subtotal MethodInfo operadorTotal = t.GetMethod("Calculo_total"); //operador es un metodo generico que refleja la funcionalidad de Calculo total decimal lineaBase = 0; EjecucionCalculada respuesta = new EjecucionCalculada(); List <object> listadoParaSubtotal = new List <object>(); List <object> listadoParaTotal = new List <object>(); string msg = ""; ejecuciones = await controlEjecucion.getFromIndicador(indicador.id); foreach (Ejecucion registro in ejecuciones) { switch (registro.Periodo.tipo) { case "periodo": object[] args = { registro, lineaBase }; //carga los argumentos en un objeto respuesta = (EjecucionCalculada)operadorPeriodo.Invoke(op, args); //envia los argumentos mediante invoke al metodo Calculo_periodo listadoEjecuciones.Add(respuesta); //almacena cada ejecucionCalcuada en la lista pero antes ajusta el formato con la clase unidadess de medida listadoParaSubtotal.Add(respuesta); //almacena ejecucón para el calculo del subtotal break; case "subtotal": Object[] argsSubtotal = { registro, listadoParaSubtotal, lineaBase }; //carga los argumentos en un objeto respuesta = (EjecucionCalculada)operadorSubtotal.Invoke(op, argsSubtotal); //envia los argumentos mediante invoke al metodo Calculo_subtotal listadoEjecuciones.Add(respuesta); //almacena cada ejecucionCalcuada en la lista pero antes ajusta el formato con la clase unidadess de medida listadoParaTotal.Add(respuesta); //almacena ejecucón para el calculo del subtotal listadoParaSubtotal.Clear(); break; case "Total": object[] argstotal = { registro, listadoParaTotal, lineaBase }; //carga los argumentos en un objeto respuesta = (EjecucionCalculada)operadorTotal.Invoke(op, argstotal); //envia los argumentos mediante invoke al metodo Calculo_total listadoEjecuciones.Add(respuesta); //almacena cada ejecucionCalcuada en la lista pero antes ajusta el formato con la clase unidadess de medida listadoParaTotal.Clear(); break; case "lineabase": var lb = registro.ejecutado; if (lb != null) { lb = lb.Replace(" ", ""); lb = lb.Replace("%", ""); lb = Regex.Replace(lb, "^-$", ""); lb = Regex.Replace(lb, "^_$", ""); lb = Regex.Replace(lb, "[a-zA-Z^&()<>//:@#$%;+_!¡]", ""); lb = Regex.Replace(lb, "^\\.$", ""); lb = Regex.Replace(lb, "^\\.\\.$", ""); lb = Regex.Replace(lb, "\\.", ""); } try { lineaBase = lb == "" ? 0 : System.Convert.ToDecimal(lb); } catch (System.OverflowException) { msg = "el valor ejecutado genera desbordamiento"; } break; default: break; } } } foreach (Periodo periodo in periodos) { decimal total = 0, calculado = 0; Boolean valida = false; var ejecucionesperiodo = (from ejecucionx in listadoEjecuciones where ejecucionx.idperiodo == periodo.id select ejecucionx); foreach (EjecucionCalculada calcuada in ejecucionesperiodo) { if (calcuada.cargado == true || ((calcuada.Periodo.tipo == "subtotal" || calcuada.Periodo.tipo == "Total") && calcuada.Periodo.cargado == true)) { total = total + calcuada.Indicador.ponderador; calculado = calculado + (calcuada.Calculado / 100) * calcuada.Indicador.ponderador; valida = true; } } if (total > 0) { calculado = (calculado / total) * 100; } else { calculado = 0; } EjecucionCategoria resultado = new EjecucionCategoria(); //resultado.Id = 1; resultado.Calculado = calculado; //resultado.Categoria = categoriax; resultado.IdCategoria = categoriax.id; resultado.idperiodo = periodo.id; resultado.Maximo = total; resultado.Mostrar = valida; var r = await controlEjecucionCategoria.Crear(resultado); } } return(false); }