using System; using System.Data; using System.Configuration; using System.Collections.Generic; using System.Collections; /// /// Summary description for RischioRelativo /// public class RischioRelativo_PesoPercentuale { public RischioRelativo_PesoPercentuale() { // // TODO: Add constructor logic here // } public RischioRelativo_PesoPercentuale(string area, string nomeprogetto, decimal rischio, string rischiostring, decimal peso) { _area = area; _rischio = rischio; _rischiostring = rischiostring; _peso = peso; _nomeprogetto = nomeprogetto; } private string _area; private string _nomeprogetto; private decimal _rischio; private string _rischiostring; private decimal _peso; //private TipoRitorno _tipodiritorno; private DataTable _datasource; /// /// Datatable contenente i controvalori di tutte le aree bisogno / progetti per cui vanno calcolati Peso e Rischio. /// public DataTable DataSource { get { return _datasource; } set { _datasource = value; } } public string Area { get { return _area; } set { _area = value; } } public string NomeProgetto { get { return _nomeprogetto; } set { _nomeprogetto = value; } } public decimal Rischio { get { return _rischio; } set { _rischio = value; } } /// /// Rappresentazione in stringa del Rischio relativo nel caso in cuiquesto non sia calcolabile (es VaR = n.d.) /// public string RischioString { get { return _rischiostring; } set { _rischiostring = value; } } public decimal Peso { get { return _peso; } set { _peso = value; } } /// /// Rirorna un DataTable contenente con i valori del Peso Percentuale. /// Il nome delle colonne : /// AreaBisogno /// NomeProgetto /// PesoPercentuale /// /// public DataTable calcolaPeso() { DataTable dtResult = new DataTable("dtResult"); dtResult.Columns.Add("AreaBisogno"); dtResult.Columns.Add("NomeProgetto"); dtResult.Columns.Add("PesoPercentuale",typeof(decimal)); decimal dividendo = 0; decimal divisore = 0; decimal ctvArea = 0; decimal pesopercentuale = 0; List _itemsPesoPercentuale = new List(); DataView dwAreeBisogno = new DataView(_datasource); DataTable dtAreeBisogno = dwAreeBisogno.ToTable(true, "need_area"); if (dtAreeBisogno.Rows.Count == 0) return null; foreach (DataRow drGlobale in dtAreeBisogno.Rows) { if (drGlobale["need_area"].ToString().ToLower() != "na") //escludo le risorse non allocate { //Recupero il dividendo (controvalore dell'area o del singolo progetto) DataRow[] rowFilter; rowFilter = _datasource.Select("need_area ='" + drGlobale["need_area"] + "'"); foreach (DataRow row in rowFilter) { ctvArea = Convert.ToDecimal(row["CONTROVALOREATTUALE"]); dividendo = Math.Round(ctvArea, 2); // Recupero il divisore divisore = recuperaDivisorePeso(_datasource); if (divisore == 0M) pesopercentuale = 0M; else pesopercentuale = Math.Round((dividendo / divisore) * 100, 2); _itemsPesoPercentuale.Add(new RischioRelativo_PesoPercentuale(row["NEED_AREA"].ToString(), row["nome_progetto"].ToString(), 0,string.Empty, pesopercentuale)); divisore = 0; } } } _itemsPesoPercentuale = ArrotondaLista(_itemsPesoPercentuale, TipoRitorno.PESO); foreach (RischioRelativo_PesoPercentuale obj in _itemsPesoPercentuale) { DataRow rToAdd = dtResult.NewRow(); rToAdd["AreaBisogno"] = obj.Area; rToAdd["NomeProgetto"] = obj.NomeProgetto; rToAdd["PesoPercentuale"] = obj.Peso; dtResult.Rows.Add(rToAdd); } return dtResult; } /// /// Ritorna un DataTable contenente con i controvalori totali di ciascusa area/progetto. /// I controvalori espressi qui sono già comprensivi di patrimonio non rappresentabile. /// /// public DataTable calcolaControvaloriAttuali() { DataTable dtResult = new DataTable("dtResult"); dtResult.Columns.Add("AreaBisogno"); dtResult.Columns.Add("NomeProgetto"); dtResult.Columns.Add("ControvaloreTotale", typeof(decimal)); dtResult.Columns.Add("Ordinamento_progetto", typeof(int)); foreach (DataRow dr in _datasource.Rows) { DataRow rToAdd = dtResult.NewRow(); rToAdd["AreaBisogno"] = dr["need_area"].ToString(); rToAdd["NomeProgetto"] = dr["nome_progetto"].ToString(); rToAdd["ControvaloreTotale"] = dr["ControvaloreAttuale"]== DBNull.Value ? 0 :Convert.ToDecimal(dr["ControvaloreAttuale"]); rToAdd["Ordinamento_progetto"] = dr["ORDINAMENTO_PROGETTO"] == DBNull.Value ? 0 : Convert.ToInt32(dr["ORDINAMENTO_PROGETTO"]); dtResult.Rows.Add(rToAdd); } return dtResult; } /// /// Ritorna un DataTable contenente con i valori del Rischio Relativo. /// Il nome delle colonne : /// AreaBisogno /// NomeProgetto /// RischioRelativo /// /// /// Di seguito la formula utilizzata: /// /// var area/progetto * ctv area/progetto /// ------------------------------------- /// sommatoria ( var area/progetto * ctv area/progetto ) /// /// /// public DataTable calcolaRischio() { DataTable dtResult = new DataTable("dtResult"); dtResult.Columns.Add("AreaBisogno"); dtResult.Columns.Add("NomeProgetto"); dtResult.Columns.Add("RischioRelativo",typeof(decimal)); dtResult.Columns.Add("RischioRelativoString"); decimal varpArea = 0; decimal dividendo = 0; decimal divisore = 0; decimal ctvArea = 0; decimal rischio = 0; string rischiostring = string.Empty; List _itemsRischioRelativo = new List(); List _itemsRischioRelativoAppoggio = new List(); if (_datasource.Rows.Count == 0) return null; foreach (DataRow dr in _datasource.Rows) { rischio = 0; varpArea = dr["var_needarea"]==DBNull.Value? 0 : Convert.ToDecimal(dr["var_needarea"]); ctvArea = Convert.ToDecimal(dr["controvaloreattuale"]); rischiostring = string.Empty; dividendo = varpArea * ctvArea; if (dividendo != 0) { divisore = recuperaDivisoreRischio(_datasource); rischio = Math.Round(dividendo * 100 / divisore, 2); } if (dr["var_needareastring"].ToString().ToLower() == "n.c.") rischiostring = "n.c."; _itemsRischioRelativo.Add(new RischioRelativo_PesoPercentuale(dr["NEED_AREA"].ToString(), dr["nome_progetto"].ToString(), rischio, rischiostring, 0)); } _itemsRischioRelativo = ArrotondaLista(_itemsRischioRelativo, TipoRitorno.RISCHIO); foreach (RischioRelativo_PesoPercentuale obj in _itemsRischioRelativo) { DataRow rToAdd = dtResult.NewRow(); rToAdd["AreaBisogno"] = obj.Area; rToAdd["NomeProgetto"] = obj.NomeProgetto; rToAdd["RischioRelativo"] = obj.Rischio; rToAdd["RischioRelativoString"] = obj.RischioString; dtResult.Rows.Add(rToAdd); } return dtResult; } /// /// Ritorna la sommatoria di tutte i controvalori di area/progetto * il VaR di area/progetto di tutte le area/progetto. /// /// /// private decimal recuperaDivisoreRischio(DataTable dt) { decimal returnValue = 0M; decimal ctvA = 0; decimal varA = 0; DataRow[] drFilter; object sumExt = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Ext'"); drFilter = dt.Select("NEED_AREA='Ext'"); if (sumExt.ToString() == string.Empty) sumExt = 0M; if (Convert.ToDecimal(sumExt) > 0) { ctvA = Convert.ToDecimal(sumExt); varA = Convert.ToDecimal(drFilter[0]["var_needarea"]); returnValue = (returnValue + Math.Round(ctvA * varA, 2)); } object sumLiq = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Liq'"); drFilter = dt.Select("NEED_AREA='Liq'"); if (sumLiq.ToString() == string.Empty) sumLiq = 0M; if (Convert.ToDecimal(sumLiq) > 0) { ctvA = Convert.ToDecimal(sumLiq); varA = Convert.ToDecimal(drFilter[0]["var_needarea"]); returnValue = (returnValue + Math.Round(ctvA * varA, 2)); } //object sumInv = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Inv'"); drFilter = dt.Select("NEED_AREA='Inv'"); //if (sumInv.ToString() == string.Empty) sumInv = 0M; foreach (DataRow drInvestimento in drFilter) { varA = Convert.ToDecimal(drInvestimento["var_needarea"]); ctvA = Convert.ToDecimal(drInvestimento["controvaloreattuale"]); returnValue = (returnValue + Math.Round(ctvA * varA, 2)); } object sumPre = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Pre'"); drFilter = dt.Select("NEED_AREA='Pre'"); if (sumPre.ToString() == string.Empty) sumPre = 0M; if (Convert.ToDecimal(sumPre) > 0) { ctvA = Convert.ToDecimal(sumPre); varA = Convert.ToDecimal(drFilter[0]["var_needarea"]); returnValue = (returnValue + Math.Round(ctvA * varA, 2)); } object sumRis = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Ris'"); drFilter = dt.Select("NEED_AREA='Ris'"); if (sumRis.ToString() == string.Empty) sumRis = 0M; if (Convert.ToDecimal(sumRis) > 0) { ctvA = Convert.ToDecimal(sumRis); varA = Convert.ToDecimal(drFilter[0]["var_needarea"]); returnValue = (returnValue + Math.Round(ctvA * varA, 2)); } return returnValue; } /// /// Ritorna la sommatoria di tutte i controvalori di area/progetto di tutte le area/progetto. /// /// /// private decimal recuperaDivisorePeso(DataTable dt) { decimal returnValue = 0M; decimal ctvA = 0; object sumExt = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Ext'"); if (sumExt.ToString() == string.Empty) sumExt = 0M; ctvA = Convert.ToDecimal(sumExt); returnValue = (returnValue + ctvA); object sumLiq = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Liq'"); if (sumLiq.ToString() == string.Empty) sumLiq = 0M; ctvA = Convert.ToDecimal(sumLiq); returnValue = (returnValue + ctvA); object sumInv = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Inv'"); if (sumInv.ToString() == string.Empty) sumInv = 0M; ctvA = Convert.ToDecimal(sumInv); returnValue = (returnValue + ctvA); object sumPre = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Pre'"); if (sumPre.ToString() == string.Empty) sumPre = 0M; ctvA = Convert.ToDecimal(sumPre); returnValue = (returnValue +ctvA); object sumRis = dt.Compute("Sum(CONTROVALOREATTUALE)", "NEED_AREA='Ris'"); if (sumRis.ToString() == string.Empty) sumRis = 0M; ctvA = Convert.ToDecimal(sumRis); returnValue = (returnValue + ctvA); return returnValue; } /// /// Arrotonda, aggiungendo all'oggetto piu alto la differenza per arrivare al 100%, una lista di oggetti. /// /// /// private List ArrotondaLista(List listadaarrotondare, TipoRitorno tiporitorno) { //----------------------------------------------------------- // verifico se la somma di tutti i rischi relativi è 100. decimal totale = 0M; foreach (RischioRelativo_PesoPercentuale r in listadaarrotondare) { if (tiporitorno == TipoRitorno.RISCHIO) totale += Math.Round(r.Rischio, 2); else totale += Math.Round(r.Peso, 2); } // se la somma non è 100 aggiungo o elimino la differenza all'area che ha il rischio piu alto. if (totale != 100M) { RischioRelativo_PesoPercentuale robjMax; // è l'area/progetto con valore (rischio o peso) piu grande MyItemCompare _compare = new MyItemCompare(); _compare.TipologiaRitorno = tiporitorno; listadaarrotondare.Sort(_compare); decimal diff = 0; decimal rischio_pesoTotaleAreaInvestimento = 0; // somma del rischio o del peso (a seconda della richiesta) di tutti i progetti di investimento. foreach (RischioRelativo_PesoPercentuale obj in listadaarrotondare) { if (obj.Area.ToLower() == "inv") { if (tiporitorno == TipoRitorno.RISCHIO) rischio_pesoTotaleAreaInvestimento += obj.Rischio; else if (tiporitorno == TipoRitorno.PESO) rischio_pesoTotaleAreaInvestimento += obj.Peso; } } robjMax = listadaarrotondare.ToArray()[listadaarrotondare.Count - 1]; if (tiporitorno == TipoRitorno.RISCHIO) { if (rischio_pesoTotaleAreaInvestimento > robjMax.Rischio) { List listadaarrotondare_appoggio = listadaarrotondare; // devo prendere il progetto di investimento piu alto. listadaarrotondare_appoggio = listadaarrotondare.FindAll(delegate(RischioRelativo_PesoPercentuale r) { return (r.Area.ToLower() == "inv"); }); listadaarrotondare_appoggio.Sort(_compare); robjMax = listadaarrotondare_appoggio.ToArray()[listadaarrotondare_appoggio.Count - 1]; } } else if (tiporitorno == TipoRitorno.PESO) { if (rischio_pesoTotaleAreaInvestimento > robjMax.Peso) { List listadaarrotondare_appoggio = listadaarrotondare; // devo prendere il progetto di investimento piu alto. listadaarrotondare_appoggio = listadaarrotondare.FindAll(delegate(RischioRelativo_PesoPercentuale r) { return (r.Area.ToLower() == "inv"); }); listadaarrotondare_appoggio.Sort(_compare); robjMax = listadaarrotondare_appoggio.ToArray()[listadaarrotondare_appoggio.Count - 1]; } } // ricavo la differenza if (totale == 0) diff = 0; else diff = 100 - totale; foreach (RischioRelativo_PesoPercentuale objToUpdate in listadaarrotondare) { if (objToUpdate.Area == robjMax.Area && objToUpdate.NomeProgetto == robjMax.NomeProgetto) { if (tiporitorno == TipoRitorno.PESO) objToUpdate.Peso += diff; else objToUpdate.Rischio += diff; } } return listadaarrotondare; } else //== 100 { return listadaarrotondare; } } } public class Rischio { private decimal _fattoreribasamento = 0; private decimal _ribasamentototale = 0; private string _area = string.Empty; private string _nomeprogetto = string.Empty; public Rischio(string Area, string NomeProgetto, decimal FattoreRibasamento) { _area = Area; _nomeprogetto = NomeProgetto; _fattoreribasamento = FattoreRibasamento; } public string Area { get { return _area; } set { _area = value; } } public string NomeProgetto { get { return _nomeprogetto; } set { _nomeprogetto = value; } } public decimal RibasamentoTotale { get { return _ribasamentototale; } set { _ribasamentototale = value; } } public decimal FattoreRibasamento { get { return _fattoreribasamento; } set { _fattoreribasamento = value; } } } public enum TipoRitorno { RISCHIO, PESO } public class MyItemCompare : IComparer { private TipoRitorno _tipologiaritorno; public TipoRitorno TipologiaRitorno { get { return _tipologiaritorno; } set { _tipologiaritorno = value; } } /// /// Compara due struttire di tipo MyItem /// /// MyItem /// MyItem /// 0 = sono uguali, -1 y è maggiore, 1 x è maggiore public int Compare(RischioRelativo_PesoPercentuale x, RischioRelativo_PesoPercentuale y) { if (x == null) { if (y == null) { // Se x è null e y è null, sono uguali return 0; } else { // Se x è null e y non è null, y è maggiore return -1; } } else { // Se x non è null... if (y == null) // ...e y è null, x è magiore. { return 1; } else { // ...e y non è null, confronto la categoria int retval; if (_tipologiaritorno == TipoRitorno.RISCHIO) retval = (x.Rischio).CompareTo(y.Rischio); else retval = (x.Peso).CompareTo(y.Peso); if (retval != 0) { // Se la categoria non è uguale ritorno il valore di retval return retval; } else { // Se la categoria è la stessa, allora devo ordinare per la descrizione return CheckNull(x.Area).CompareTo(CheckNull(y.Area)); } } } } private string CheckNull(string val) { if (val == null) return ""; return val; } }