627 lines
19 KiB
C#
627 lines
19 KiB
C#
using System;
|
|
using System.Data;
|
|
using System.Configuration;
|
|
using System.Collections.Generic;
|
|
using System.Collections;
|
|
|
|
|
|
/// <summary>
|
|
/// Summary description for RischioRelativo
|
|
/// </summary>
|
|
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;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Datatable contenente i controvalori di tutte le aree bisogno / progetti per cui vanno calcolati Peso e Rischio.
|
|
/// </summary>
|
|
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; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rappresentazione in stringa del Rischio relativo nel caso in cuiquesto non sia calcolabile (es VaR = n.d.)
|
|
/// </summary>
|
|
public string RischioString
|
|
{
|
|
get { return _rischiostring; }
|
|
set { _rischiostring = value; }
|
|
}
|
|
|
|
public decimal Peso
|
|
{
|
|
get { return _peso; }
|
|
set { _peso = value; }
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Rirorna un DataTable contenente con i valori del Peso Percentuale.
|
|
/// Il nome delle colonne :
|
|
/// AreaBisogno
|
|
/// NomeProgetto
|
|
/// PesoPercentuale
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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<RischioRelativo_PesoPercentuale> _itemsPesoPercentuale = new List<RischioRelativo_PesoPercentuale>();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Ritorna un DataTable contenente con i controvalori totali di ciascusa area/progetto.
|
|
/// I controvalori espressi qui sono già comprensivi di patrimonio non rappresentabile.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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"] = Convert.ToInt32(dr["ORDINAMENTO_PROGETTO"]);
|
|
dtResult.Rows.Add(rToAdd);
|
|
|
|
}
|
|
|
|
return dtResult;
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 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 )
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
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<RischioRelativo_PesoPercentuale> _itemsRischioRelativo = new List<RischioRelativo_PesoPercentuale>();
|
|
List<Rischio> _itemsRischioRelativoAppoggio = new List<Rischio>();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Ritorna la sommatoria di tutte i controvalori di area/progetto * il VaR di area/progetto di tutte le area/progetto.
|
|
/// </summary>
|
|
/// <param name="dt"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ritorna la sommatoria di tutte i controvalori di area/progetto di tutte le area/progetto.
|
|
/// </summary>
|
|
/// <param name="dt"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Arrotonda, aggiungendo all'oggetto piu alto la differenza per arrivare al 100%, una lista di oggetti.
|
|
/// </summary>
|
|
/// <param name="listadaarrotondare"></param>
|
|
/// <returns></returns>
|
|
private List<RischioRelativo_PesoPercentuale> ArrotondaLista(List<RischioRelativo_PesoPercentuale> 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<RischioRelativo_PesoPercentuale> 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<RischioRelativo_PesoPercentuale> 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<RischioRelativo_PesoPercentuale>
|
|
{
|
|
|
|
private TipoRitorno _tipologiaritorno;
|
|
|
|
public TipoRitorno TipologiaRitorno
|
|
{
|
|
get { return _tipologiaritorno; }
|
|
set { _tipologiaritorno = value; }
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Compara due struttire di tipo MyItem
|
|
/// </summary>
|
|
/// <param name="x">MyItem</param>
|
|
/// <param name="y">MyItem</param>
|
|
/// <returns>0 = sono uguali, -1 y è maggiore, 1 x è maggiore </returns>
|
|
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;
|
|
}
|
|
}
|