using System;
using Consulenza.ReportWriter.Business;
using Consulenza.ReportWriter.Business.OBJ_PDF;
using System.Data;
using System.Collections.Generic;
using Consulenza.ReportCommon;
using Consulenza.ReportWriter.Business.CUSTOM_PDF.ConsulenzaUnica;
using System.Linq;
using Consulenza.ReportWriter.Business.Entity;
using Consulenza.DataServices.fideuram.data.service;
using Consulenza.ReportWriter.Business.CHART_PDF;
using Dundas.Charting.WebControl;

namespace Consulenza.ReportWriter.Manager.Section.Unica
{
    public class S55 : Entity.Section
    {
        /// <summary>
        ///S55.PropostaDettaglioProdotti idSezione = 98 
        /// </summary>
        bool notaCodici;
        public S55(EnvironmentFacade environmentFacade, int idSection)
            : base(environmentFacade, idSection)
        {
            try
            {
                Draw();
            }
            catch (Exception ex)
            {
                SectionLogger.Write("S55", ex.Message, SectionLoggerMessageLevel.E, EnvironmentFacade.ReportEnvironment);
            }
        }

        protected override sealed void Draw()
        {
            var dati = GetDataSet();
            bool isAdeguata = datiSeiUnico.flagAdeguatezzaPro();

            AddElement(new PagePDF(PagePDF.PagePDFType.Generic));
            var intestazione = new SectionHeadingPDF(
                   (isAdeguata ? "Proposta" : "Operazioni richieste") + ": dettaglio prodotti",

                    EnvironmentFacade.RendererFacade.XLeftLimit,
                    EnvironmentFacade.RendererFacade.YUpperLimit,
                    EnvironmentFacade.ReportEnvironment.FontFamily);

            AddElement(intestazione.ToElement());

            if (getTesto1().Length > 0)
            {
                AddElement(new SpacePDF(20));
                AddElement(new FormattedTextAreaPDF(getTesto1(), EnvironmentFacade.RendererFacade.XLeftLimit) {FontSize=7, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                AddElement(new SpacePDF(10));
            }
            var tabellaAreeUltima = new TablePDF();
            Boolean isCP = false;
            int dimensione = dati.Tables.Count;
            foreach (DataTable dt in dati.Tables)
            {
                dimensione--;
                if (dt.Rows.Count > 1)  //0=totale
                {
                    var tabellaAree = new TablePDF(EnvironmentFacade.RendererFacade.XLeftLimit, dt)
                    {
                        Style = Style.ConsulenzaUnica,
                        Footer = false,
                        AlternateRow = false,
                        ShowBorderLastLine = false,
                        HeaderHeight = 27,
                        //FooterHeight=25,
                        RowHeight = 25,
                        TitleRow = true,
                        TitleRowText = dt.Rows[0]["titolo"].ToString(),
                        TitleRowBorder = BorderTitleRowType.Nessuno,
                        TitleRowSpace = 13

                    };

                    // Modifica per Saving Map
                    tabellaAree.Columns.Add(new ColumnPDF("SavingMap", 13, HorizontalAlignmentType.Sinistra, false, false, 6, ColumnType.Immagine, "SavingMap", string.Empty) { DeltaYContent = 10, ScaleColumnTypeImage = 0.50F });
                    // Fine Modifica
                    tabellaAree.Columns.Add(new ColumnPDF("Descrizione", 120, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Testo, "Descrizione", "Prodotto") { HeaderFontSize = 7 });
                    tabellaAree.Columns.Add(new ColumnPDF("StatoCP", 29, HorizontalAlignmentType.Destra, false, false, 7, ColumnType.Immagine, "StatoCP", string.Empty) { DeltaYContent = 10, ScaleColumnTypeImage = 0.50F });
                    tabellaAree.Columns.Add(new ColumnPDF("Controvaloreattuale", 90, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Decimale, "Controvaloreattuale", "Controvalore<br>attuale (€)") { HeaderPaddingLeft = 10, HeaderFontSize = 7, PaddingRight = 6 });
                    tabellaAree.Columns.Add(new ColumnPDF("ApportiDisinvest", 80, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Decimale, "ApportiDisinvest", "Apporti/<br>Disinvest. (€)") { HeaderPaddingLeft = 7, HeaderFontSize = 7, PaddingRight = 6 });
                    tabellaAree.Columns.Add(new ColumnPDF("Controvaloreproposto", 90, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Decimale, "Controvaloreproposto", "Controvalore<br>" + (isAdeguata ? "proposto (€)" : "prospettico (€)")) { HeaderPaddingLeft = 7, HeaderFontSize = 7, PaddingRight = 6 });
                    tabellaAree.Columns.Add(new ColumnPDF("Rischiocredito", 53, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Testo, "Rischiocredito", "Rischio<br>Credito") { HeaderPaddingLeft = 7, HeaderFontSize = 7, PaddingRight = 6 });
                    tabellaAree.Columns.Add(new ColumnPDF("VaR", 35, HorizontalAlignmentType.Sinistra, false, false, 7, ColumnType.Testo, "VaR", "VaR (%)") { HeaderPaddingLeft = 0, HeaderFontSize = 7, PaddingRight = 4 });

                    tabellaAreeUltima = tabellaAree;
                    for (int e = 0; e < dt.Rows.Count; e++)
                    {
                        DataRow dr = dt.Rows[e];
                        int indexVar = 5;

                        switch (dr["tipoRow"].ToString())
                        {
                            case "totale":
                                for (int c = 0; c < tabellaAree.Columns.Count; c++)
                                {
                                    tabellaAree.Cells[c, e].BackgroundColor = ColorPDF.Standard_Grigio_SfondoColonnaTabella;
                                    tabellaAree.Cells[c, e].FontBold = true;
                                   
                                }
                                if (dr["nota"].ToString().Length > 0)
                                {
                                    AddElement(new FormattedTextAreaPDF("(*) " + dr["nota"].ToString(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                                    dr[indexVar] += "*";
                                }
                                break;
                            case "sottotitolo":
                                for (int c = 0; c < tabellaAree.Columns.Count; c++)
                                {
                                    tabellaAree.Cells[c, e].BackgroundColor = ColorPDF.Standard_Grigio_SfondoColonnaTabella; 
                                    tabellaAree.Cells[c, e].FontBold = true;
                                }
                                break;
                            case "Dettaglio":
                                if (dr["StatoCP"].ToString().Length > 0)
                                    isCP = true;
                                break;
                            default:
                                break;
                        }

                    }

                    int a = 0;
                    foreach (DataRow ro in dt.Rows)
                    {
                        
                        tabellaAree.Cells[2, a].HorizontalAlignment =
                            tabellaAree.Cells[3, a].HorizontalAlignment =
                            tabellaAree.Cells[4, a].HorizontalAlignment =
                            tabellaAree.Cells[5, a].HorizontalAlignment =
                            tabellaAree.Cells[6, a].HorizontalAlignment = HorizontalAlignmentType.Destra;
                        a++;
                    }
                    if (isCP && dimensione == 0)
                    {
                        tabellaAreeUltima.Footer = true;
                        tabellaAreeUltima.Notes.Add(
                           new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella,
                                               "Prodotto con servizio Step Up attivo. Gli apporti indicati nella colonna \"Controvalore Proposto\" tengono in considerazione il versamento in fase di Sottoscrizione e gli importi relativi allo Step Up in uscita.",
                                               new[] { "" },
                                               string.Empty,
                                               TableNotePDF.TableNoteAsteriskPositionType.PieDiTabella,
                                               new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.60F, "cpInUscita.png"))
                           { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Left });
                        tabellaAreeUltima.Notes.Add(
                         new TableNotePDF(TableNotePDF.TableNotePositionType.PièDiTabella,
                                             "Prodotto con servizio Step Up attivo. Gli apporti indicati nella colonna \"Controvalore Proposto\" tengono in considerazione il versamento in fase di Sottoscrizione e gli importi relativi allo Step Up in entrata.",
                                             new[] { "" },
                                             string.Empty,
                                             TableNotePDF.TableNoteAsteriskPositionType.PieDiTabella,
                                             new ImagePDF(EnvironmentFacade.RendererFacade.XLeftLimit, 0.60F, "cpInEntrata.png"))
                         { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Left });
                    }

                    AddElement(tabellaAree);

  
                    #region NOTE AD AZ 90, RM RS PPR, KM KS PPI SOTTOSCRIZIONE, KM KS PPI CONTRATTO
                    string noteText = "*";
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaAD")) != null)
                    {
                        
                        //for (int b = 0; b < dt.Rows.Count - 1; b++)
                        for (int b = 0; b < dt.Rows.Count; b++)
                        {
                            
                            if (Convert.ToBoolean(dt.Rows[b]["notaAD"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText +") "+ getNotaAD(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";

                    }

                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaAZ")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaAZ"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaAZ(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaRM")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaRM"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaRM(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaRS")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaRS"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaRS(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaCKS")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaCKS"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaCKS(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaCKE")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaCKE"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaCKE(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaSKS")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaSKS"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaSKS(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
                    if (dt.AsEnumerable().FirstOrDefault(o => o.Field<bool>("notaSKE")) != null)
                    {
                        for (int b = 0; b < dt.Rows.Count - 1; b++)
                        {
                            if (Convert.ToBoolean(dt.Rows[b]["notaSKE"]))
                                tabellaAree.Cells[0, b].Value += dt.Rows[b]["Descrizione"].ToString() + noteText;
                        }
                        AddElement(new SpacePDF(5));
                        AddElement(new FormattedTextAreaPDF("(" + noteText + getNotaSKE(), EnvironmentFacade.RendererFacade.XLeftLimit) { FontSize = 6, TextHorizontalAlign = ceTe.DynamicPDF.TextAlign.Justify });
                        noteText += "*";
                    }
 
                    #endregion

                }
                AddElement(new SpacePDF(5));
            }
        }
        /// <summary>
        /// Recupera i dati necessari alla Section restituendo un DataTable.
        /// </summary>
        /// <returns></returns>
        protected sealed override DataTable GetDataTable()
        {
            return null;
        }

        /// <summary>
        /// Recupera i dati necessari alla Section restituendo un DataSet.
        /// </summary>
        /// <returns></returns>
        protected sealed override DataSet GetDataSet()
        {
            #region Estrazione dati + definizione Dataset
            var ds = new DataSet();
            var aree  = datiSeiUnico.propostaUnit().stPianificazioneVerticale.stAreePianificazione;
            var dettaglioProdotti = datiSeiUnico.propostaUnit().dettaglioProdotti.dettaglioProdotti.Where(x => x.ctvPro != 0 || (x.ctvPro == 0 && x.ctvAttuale != 0) || (x.isCPUscita));
            
            #endregion

            string[] notChAgg = { "PAT", "RA" };

            #region Checkbox - Opzione Raggruppamento
            var raggruppaProdotti = getRaggruppaProdotti();
            #endregion

            var operazioni = datiSeiUnico.propostaUnit().dettaglioOperazioni.elencoDettagliOperazioni;

            #region RaggruppaProdotti.AreaBisogno
            if (raggruppaProdotti == RaggruppaProdotti.AreaBisogno)
            {
                string codArea = "";
                rsAggregatoPosizioni itemPreEss = null;
                rsAggregatoPosizioni itemPreSec = null;
                var elencoAreeProgetti = datiSeiUnico.propostaUnit().dettaglioProdotti.elencoAggregati.elencoAreeProgetti;
                var areeDisplayInfos = datiSeiUnico.displayInfos().areeDisplayInfos;
                
                int count = 0;
                int indexTotaleInvPre = 0;
                var listaelencoaggregati = (from o in elencoAreeProgetti
                                                              join a in areeDisplayInfos on o.chiaveAggregazione.ToUpper() equals a.key.ToUpper()
                                                              where o.posizioniAggregate != null && !notChAgg.Contains(o.chiaveAggregazione) /*&& o.ctvPro != 0 && o.ctvAttuale != 0*/
                                                              orderby a.value.order, o.ctvPro descending
                                                              select o).ToList();


                var indexPreEssenziale = listaelencoaggregati.ToList().FindIndex(o => o.descrizione.Equals("Previdenza Essenziale"));
                var indexPreSecondaria = listaelencoaggregati.ToList().FindIndex(o => o.descrizione.Equals("Previdenza Secondaria"));
                if (indexPreEssenziale > indexPreSecondaria)
                {
                    itemPreEss = indexPreEssenziale != -1 ? listaelencoaggregati[indexPreEssenziale] : null;
                    itemPreSec = indexPreSecondaria != -1 ? listaelencoaggregati[indexPreSecondaria] : null;
                    if (itemPreEss != null && itemPreSec != null)//se non ci sono tutte e due l'ordinamento vien da sé
                    {
                        listaelencoaggregati[indexPreSecondaria] = itemPreEss;
                        listaelencoaggregati[indexPreEssenziale] = itemPreSec;
                    }
                }
                foreach (rsAggregatoPosizioni areeProgetti in listaelencoaggregati.Where(x => x.ctvPro != 0 || (x.ctvPro == 0 && x.ctvAttuale != 0)))
                {
                    if (codArea != areeProgetti.chiaveAggregazione)
                    { 
                        codArea = areeProgetti.chiaveAggregazione;
                        ds.Tables.Add(new DataTable(codArea));
                        ds.Tables[codArea].Columns.Add(new DataColumn("SavingMap", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("Descrizione", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("StatoCP", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("Controvaloreattuale", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("ApportiDisinvest", typeof(decimal)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("Controvaloreproposto", typeof(decimal)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("Rischiocredito", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("VaR", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("tipoRow", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("titolo", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("nota", typeof(string)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaAD", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaAZ", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaRM", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaRS", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaCKS", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaCKE", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaSKS", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("notaSKE", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("BackgroundColor", typeof(bool)));
                        ds.Tables[codArea].Columns.Add(new DataColumn("FontBold", typeof(bool)));

                    }

                    if (areeProgetti.chiaveProgettoLinea == null)
                    {

                        if (codArea.Equals("Inv") || codArea.Equals("Pre"))
                        {
                            indexTotaleInvPre = count;
                            count++;
                            continue;
                        }
                    }

                    if (areeProgetti.chiaveAggregazione.Equals("Inv") || areeProgetti.chiaveAggregazione.Equals("Pre"))
                    {
                        DataRow dr = ElencoProdotti(ds.Tables[codArea], areeProgetti, areeProgetti.chiaveAggregazione.Equals("Inv") ? "Investimento" : "Previdenza", areeProgetti.descrizione, true, true);

                        
                    }
        
                    foreach (rsSTPosizione dettaglioProdotto in from a in areeProgetti.posizioniAggregate
                                                                join d in dettaglioProdotti on new { a.chiaveAggregazione, a.posizionePro } equals new { d.chiaveAggregazione, d.posizionePro }
                                                                orderby d.ctvPro descending
                                                                select d)
                    {
                        var operazione = operazioni.Where(o => o.chiaveAggregazione == dettaglioProdotto.chiaveAggregazione && o.posizionePro == dettaglioProdotto.posizionePro).FirstOrDefault();
                        string codcontratto = operazione != null ? operazione.listaOperzioni[0].stDettaglioContratto != null ?  operazione.listaOperzioni[0].stDettaglioContratto.tipoContratto :  "": "";
                        string tipoOperazione = operazione != null ? operazione.listaOperzioni[0].codTipoOperazione : "";
                        ElencoProdotti(ds.Tables[codArea], dettaglioProdotto, "", new AreaBisogno(codArea).Nome, codcontratto, tipoOperazione);
                     }
                 
                    if (areeProgetti.chiaveAggregazione == "Inv" || areeProgetti.chiaveAggregazione == "Pre")
                    {
                        if ((count + 1) > listaelencoaggregati.Count - 1 || !listaelencoaggregati[count].chiaveAggregazione.Equals(areeProgetti.chiaveAggregazione))
                        {
                            ElencoProdottiTotali(ds.Tables[codArea], listaelencoaggregati[indexTotaleInvPre]);//area inv o pre x totale
                            
                        }
                    }
                    else
                    {
                        ElencoProdottiTotali(ds.Tables[codArea], areeProgetti);//area x totale
                    }
                    count++;
                }
                
               
            }

            #endregion

            #region RaggruppaProdotti.Contratto
            if (raggruppaProdotti == RaggruppaProdotti.Contratto)
            {
                var elencoContrattiLinea = datiSeiUnico.propostaUnit().dettaglioProdotti.elencoAggregati.elencoContrattiLinea;
                string nomeLineaContratto = "";
                var listaContrattiLinee = (from o in elencoContrattiLinea
                                           where o.posizioniAggregate != null && !notChAgg.Contains(o.chiaveAggregazione)
                                           select o).ToList();

                var listaContratti = (from o in listaContrattiLinee where o.chiaveProgettoLinea == null orderby o.ctvPro descending select o).ToList();
                var listaLinee = (from o in listaContrattiLinee where o.chiaveProgettoLinea != null orderby o.ctvPro descending select o).ToList();

              
                foreach (rsAggregatoPosizioni contratto in listaContratti)
                {

                    if (nomeLineaContratto != contratto.chiaveAggregazione && contratto.chiaveProgettoLinea == null)
                    {

                        nomeLineaContratto = contratto.chiaveAggregazione;
                        ds.Tables.Add(new DataTable(nomeLineaContratto));

                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("SavingMap", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("Descrizione", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("StatoCP", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("Controvaloreattuale", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("ApportiDisinvest", typeof(decimal)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("Controvaloreproposto", typeof(decimal)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("Rischiocredito", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("VaR", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("tipoRow", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("titolo", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("nota", typeof(string)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaAD", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaAZ", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaRM", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaRS", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaCKS", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaCKE", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaSKS", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("notaSKE", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("BackgroundColor", typeof(bool)));
                        ds.Tables[nomeLineaContratto].Columns.Add(new DataColumn("FontBold", typeof(bool)));

                    }

                   
                        foreach (rsSTPosizione dettaglioProdotto in from a in contratto.posizioniAggregate
                                                                    join d in dettaglioProdotti on new { a.chiaveAggregazione, a.posizionePro } equals new { d.chiaveAggregazione, d.posizionePro }
                                                                    where a.flagLinea == false
                                                                    orderby d.ctvPro descending
                                                                    select d)
                        {
                            var operazione = operazioni.Where(o => o.chiaveAggregazione == dettaglioProdotto.chiaveAggregazione && o.posizionePro == dettaglioProdotto.posizionePro).FirstOrDefault();

                            string codcontratto = operazione != null ? operazione.listaOperzioni[0].stDettaglioContratto != null ? operazione.listaOperzioni[0].stDettaglioContratto.tipoContratto : "" : "";
                            string tipoOperazione = operazione != null ? operazione.listaOperzioni[0].codTipoOperazione : "";
                            ElencoProdotti(ds.Tables[nomeLineaContratto], dettaglioProdotto, "", contratto.descrizione, codcontratto, tipoOperazione);
                        }

                    

                    foreach (rsAggregatoPosizioni linea in listaLinee)
                    {
                        if (linea.chiaveAggregazione.Equals(contratto.chiaveAggregazione))
                        {
                            DataRow dr = ElencoProdotti(ds.Tables[nomeLineaContratto], linea, contratto.descrizione, linea.descrizione, true, true);

                            foreach (rsSTPosizione dettaglioProdotto in from a in linea.posizioniAggregate
                                                                        join d in dettaglioProdotti on new { a.chiaveAggregazione, a.posizionePro } equals new { d.chiaveAggregazione, d.posizionePro }
                                                                        where a.flagLinea == true && d.ctvPro != 0 && d.ctvAttuale != 0
                                                                        orderby d.ctvPro descending
                                                                        select d)
                            {
                                var operazione = operazioni.Where(o => o.chiaveAggregazione == dettaglioProdotto.chiaveAggregazione && o.posizionePro == dettaglioProdotto.posizionePro).FirstOrDefault();

                                string codcontratto = operazione != null ? operazione.listaOperzioni[0].stDettaglioContratto != null ? operazione.listaOperzioni[0].stDettaglioContratto.tipoContratto : "" : "";
                                string tipoOperazione = operazione != null ? operazione.listaOperzioni[0].codTipoOperazione : "";

                                //if (dettaglioProdotto.ctvPro != 0 && dettaglioProdotto.ctvAttuale != 0)
                                    ElencoProdotti(ds.Tables[nomeLineaContratto], dettaglioProdotto, "", linea.descrizione, codcontratto, tipoOperazione);
                            }
                        }
                    
                    }
                    ElencoProdottiTotali(ds.Tables[nomeLineaContratto], contratto);

                }
            }

            #endregion

            #region RaggruppaProdotti.Categoria
            if (raggruppaProdotti == RaggruppaProdotti.Categoria)
            {
                var displaycat = datiSeiUnico.displayInfos().categoriaDisplayInfos;
                var elencoCategoria = datiSeiUnico.propostaUnit().dettaglioProdotti.elencoAggregati.elencoCategoria;
                foreach (rsAggregatoPosizioni Categoria in from o in elencoCategoria
                                                           join l in displaycat on o.descrizione.ToUpper().Replace(" ", "") equals l.key
                                                           where o.posizioniAggregate != null && !notChAgg.Contains(o.chiaveAggregazione)
                                                           orderby l.value.order, o.ctvPro descending
                                                           select o)
                {
                    ds.Tables.Add(new DataTable(Categoria.chiaveAggregazione));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("SavingMap", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("Descrizione", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("StatoCP", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("Controvaloreattuale", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("ApportiDisinvest", typeof(decimal)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("Controvaloreproposto", typeof(decimal)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("Rischiocredito", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("VaR", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("tipoRow", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("titolo", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("nota", typeof(string)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaAD", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaAZ", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaRM", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaRS", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaCKS", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaCKE", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaSKS", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("notaSKE", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("BackgroundColor", typeof(bool)));
                    ds.Tables[Categoria.chiaveAggregazione].Columns.Add(new DataColumn("FontBold", typeof(bool)));
                    foreach (rsSTPosizione dettaglioProdotto in from a in Categoria.posizioniAggregate
                                                                join d in dettaglioProdotti on new { a.chiaveAggregazione, a.posizionePro } equals new { d.chiaveAggregazione, d.posizionePro }
                                                                orderby d.ctvPro descending
                                                                select d)
                    {
                        var operazione = operazioni.Where(o => o.chiaveAggregazione == dettaglioProdotto.chiaveAggregazione && o.posizionePro == dettaglioProdotto.posizionePro).FirstOrDefault();

                        string codcontratto = operazione != null ? operazione.listaOperzioni[0].stDettaglioContratto != null ? operazione.listaOperzioni[0].stDettaglioContratto.tipoContratto : "" : "";
                        string tipoOperazione = operazione != null ? operazione.listaOperzioni[0].codTipoOperazione : "";
                      //  if (dettaglioProdotto.ctvPro != 0) //Fix #4948
                            ElencoProdotti(ds.Tables[Categoria.chiaveAggregazione], dettaglioProdotto, "", Categoria.descrizione, codcontratto, tipoOperazione);
                    }
                    ElencoProdottiTotali(ds.Tables[Categoria.chiaveAggregazione], Categoria);
                    //ElencoProdotti(ds.Tables[Categoria.chiaveAggregazione], Categoria, "", Categoria.descrizione, true, true);
                }


            }
            #endregion
 
            return ds;
        }
        public virtual RaggruppaProdotti getRaggruppaProdotti()
        {
            return GetOption<Opzione6_2>().RaggruppaProdotti;
        }
        private DataRow ElencoProdotti(DataTable prodotti, rsAggregatoPosizioni areaProgetti, string codArea, string descrizione, bool fontBold = true, bool backGroundColor = true)
        {
            DataRow dr = prodotti.NewRow();

            dr["SavingMap"] = "";
            dr["Descrizione"] = areaProgetti.descrizione;
            dr["StatoCP"] = "";
            dr["Controvaloreattuale"] = areaProgetti.ctvAttuale;
            dr["ApportiDisinvest"] = areaProgetti.investi + areaProgetti.disinvesti * (-1);
            dr["Controvaloreproposto"] = areaProgetti.ctvPro;
            dr["Rischiocredito"] = "-";
            dr["VaR"] = areaProgetti.prometeiaInfos != null ? areaProgetti.prometeiaInfos.varDecodificato : "-";
            dr["tipoRow"] = "sottotitolo";
            dr["titolo"] = codArea;
            dr["nota"] = getNotaRow1(100m);
            dr["notaAD"] = false;
            dr["notaAZ"] = false;
            dr["notaRM"] = false;
            dr["notaRS"] = false;
            dr["notaCKS"] = false;
            dr["notaCKE"] = false;
            dr["notaSKS"] = false;
            dr["notaSKE"] = false;
            dr["BackgroundColor"] = true;
            dr["FontBold"] = true;
            prodotti.Rows.Add(dr);
            return dr;
        }
        private DataRow ElencoProdottiold(DataTable prodotti, rsAggregatoPosizioni areaProgetti, string codArea, string descrizione, bool fontBold = false, bool backGroundColor = false)
        {
            
            DataRow dr = prodotti.NewRow();
            
            dr["Descrizione"] = codArea != "" ? descrizione : "Totale " + descrizione;
            
            dr["Controvaloreattuale"] = codArea != "" ? areaProgetti.ctvAttuale : prodotti.AsEnumerable().Where(x => !x.Field<bool>("FontBold")).Sum(x => x.Field<decimal>("Controvaloreattuale"));
           
            dr["ApportiDisinvest"] = codArea != "" ? areaProgetti.investi + areaProgetti.disinvesti * (-1) : prodotti.AsEnumerable().Where(x => !x.Field<bool>("FontBold")).Sum(x => x.Field<decimal>("ApportiDisinvest"));
            dr["Controvaloreproposto"] = codArea != "" ? areaProgetti.ctvPro : prodotti.AsEnumerable().Where(x => !x.Field<bool>("FontBold")).Sum(x => x.Field<decimal>("Controvaloreproposto"));
            dr["Rischiocredito"] = "-";
            dr["VaR"] = codArea != "" ? areaProgetti.prometeiaInfos.varDecodificato : "";
            dr["tipoRow"] = "totale";
            dr["titolo"] =  codArea != "" ? codArea : descrizione;
            dr["nota"] = getNotaRow1(100m);
            dr["notaAD"] = false;
            dr["notaAZ"] = false;
            dr["notaRM"] = false;
            dr["notaRS"] = false;
            dr["notaCKS"] = false;
            dr["notaCKE"] = false;
            dr["notaSKS"] = false;
            dr["notaSKE"] = false;
            dr["FontBold"] = fontBold;
            dr["BackgroundColor"] = backGroundColor;
            prodotti.Rows.Add(dr);
            return dr;
        }
        
        private DataRow ElencoProdotti(DataTable prodotti, rsSTPosizione dettaglioProdotto, string codArea, string descrizione,string codContratto, string codTipoOperazione, bool fontBold = false, bool backGroundColor = false)
        {
            DataRow dr = prodotti.NewRow();

            if (dettaglioProdotto.savingMap)
                dr["SavingMap"] = "SavingMap.png";
            else
                dr["SavingMap"] = "";
 
            dr["Descrizione"] = dettaglioProdotto.prodotto.nomeProdotto;
            dr["StatoCP"] = "";
            if (dettaglioProdotto.isCPEntrata)
                dr["StatoCP"] = "cpInEntrata.png";
            else if (dettaglioProdotto.isCPUscita)
                dr["StatoCP"] = "cpInUscita.png";
            dr["Controvaloreattuale"] = dettaglioProdotto.ctvAttuale;
            dr["ApportiDisinvest"] = dettaglioProdotto.investi + dettaglioProdotto.disinvesti * (-1);
            dr["Controvaloreproposto"] = dettaglioProdotto.ctvPro;
            dr["Rischiocredito"] = dettaglioProdotto.prodotto.rischioCreditoDec != null ?Helper.resultValueVariousString(dettaglioProdotto.prodotto.rischioCreditoDec) : "";
            dr["VaR"] = dettaglioProdotto.prodotto.varProDec;
            dr["tipoRow"] = "Dettaglio";
            dr["titolo"] = descrizione;
            dr["nota"] = "";
            dr["notaAD"] = dettaglioProdotto.prodotto.codInterno == "90" && codTipoOperazione == "AD";
            dr["notaAZ"] = dettaglioProdotto.prodotto.codInterno == "90" && codTipoOperazione == "AZ";
            dr["notaRM"] = dettaglioProdotto.prodotto.codInterno == "RM" && codContratto == "PPR" && (codTipoOperazione=="NS" || codTipoOperazione=="TR");
            dr["notaRS"] = dettaglioProdotto.prodotto.codInterno == "RS" && codContratto == "PPR" && (codTipoOperazione == "NS" || codTipoOperazione == "TR");
            dr["notaCKS"] = dettaglioProdotto.prodotto.codInterno == "KS" && dettaglioProdotto.ctvPro > 0 && codTipoOperazione=="CV" && codContratto=="PPI";//conversione
            dr["notaCKE"] = dettaglioProdotto.prodotto.codInterno == "KE" && dettaglioProdotto.ctvPro > 0 && codTipoOperazione == "CV" && codContratto == "PPI";//conversione
            dr["notaSKS"] = dettaglioProdotto.prodotto.codInterno == "KS" && codTipoOperazione == "NS" && codContratto == "PPI"; //sottoscrizione
            dr["notaSKE"] = dettaglioProdotto.prodotto.codInterno == "KE" && codTipoOperazione == "NS" && codContratto == "PPI";
            dr["FontBold"] = fontBold;
            dr["BackgroundColor"] = backGroundColor;
                
            prodotti.Rows.Add(dr);
            return dr;
        }

        private DataRow ElencoProdottiTotali(DataTable prodotti, rsAggregatoPosizioni areaProgetti)
        {
            DataRow dr = prodotti.NewRow();
            
            dr["Descrizione"] = "Totale "+ areaProgetti.descrizione;
            dr["Controvaloreattuale"] = areaProgetti.ctvAttuale;
            dr["ApportiDisinvest"] = areaProgetti.investi + areaProgetti.disinvesti * (-1);
            dr["Controvaloreproposto"] = areaProgetti.ctvPro;
            dr["Rischiocredito"] = "-";
            dr["VaR"] = areaProgetti.prometeiaInfos != null ? areaProgetti.prometeiaInfos.varDecodificato : "-";
            dr["tipoRow"] = "totale";
            dr["titolo"] = areaProgetti.descrizione;
            dr["nota"] = getNotaRow1(100m);
            dr["notaAD"] = false;
            dr["notaAZ"] = false;
            dr["notaRM"] = false;
            dr["notaRS"] = false;
            dr["notaCKS"] = false;
            dr["notaCKE"] = false;
            dr["notaSKS"] = false;
            dr["notaSKE"] = false;
            dr["BackgroundColor"] = true;
            dr["FontBold"] = true;
            prodotti.Rows.Add(dr);
            return dr;
        }
        
        public virtual string getTesto1() {
           bool Adeguata = datiSeiUnico.flagAdeguatezzaPro();
           string nota = "";
           if(!Adeguata)
               nota = "In questa scheda sono riportati i prodotti che lei attualmente detiene presso $/Banca/$ e quelli da lei richiesti al suo private banker, con evidenza delle operazioni effettuate su sua richiesta. ";
           else
               nota = "In questa scheda sono riportati i prodotti che lei attualmente detiene presso $/Banca/$ e quelli selezionati nella presente proposta, con evidenza delle operazioni effettuate. ";
           switch (GetOption<Opzione6_2>().RaggruppaProdotti) { 
               case RaggruppaProdotti.AreaBisogno:
                   nota+= "I prodotti sono raggruppati per area di bisogno e, dove necessario, per progetto di investimento.";
                   break;
               case RaggruppaProdotti.Categoria:
                   nota+= "I prodotti sono raggruppati sulla base della categoria di appartenenza.";
                   break;
               case RaggruppaProdotti.Contratto:
                   nota += "I prodotti sono raggruppati sulla base del contratto di appartenenza.";
                   break;
           }
           return Helper.ReplaceVariables(nota,EnvironmentFacade.ReportEnvironment);
        }

        public virtual string getNotaRow1(decimal gradoCopertura)
        {
            string nota = "";
            if (gradoCopertura < 100 && Convert.ToDouble(gradoCopertura) != 0)
            {
                nota += "Grado di copertura prodotti in termini di Rischio Mercato (VaR %): {0}.";
            }
            return string.Format(nota, Helper.FormatDecimal(gradoCopertura.ToString(), 2));             
        }
        public virtual string getNotaAD()
        {
            return "Adesione al Fondo Pensione Fideuram con versamento di un contributo iniziale. Gli apporti indicati rappresentano il totale dei contributi versati dall’aderente in fase di adesione.";
          
        }
        public virtual string getNotaAZ()
        {
            //string nota = "";
            //if (codInt == "90" && codTipoCont == "AZ")
                return ") Adesione al Fondo Pensione Fideuram senza versamento di un contributo iniziale. In corrispondenza del singolo comparto non è quindi possibile valorizzare gli apporti né il controvalore finale.";
            //return nota;
        }
        public virtual string getNotaRM()
        {
          return ") Prodotto a premio periodico. Gli apporti indicati rappresentano il totale dei premi versati in fase di sottoscrizione (prima rata + premio unico aggiuntivo)";
           
        }
        public virtual string getNotaRS()
        {
           return ") Prodotto a premio periodico. Gli apporti indicati rappresentano il totale dei premi versati in fase di sottoscrizione (prima rata + premio unico aggiuntivo)";
         
        }
        public virtual string getNotaCKS()
        { 
            return ") Programma periodico che prevede l’investimento iniziale nel portafoglio monetario “In Prima Persona – Linea Liquidità”. Gli apporti indicati rappresentano il totale dei premi versati su ciascun fondo al termine del programma periodico.";
         
        }
        public virtual string getNotaCKE()
        {
            return ") Programma periodico che prevede l’investimento iniziale nel portafoglio monetario “In Persona – Linea Liquidità”. Gli apporti indicati rappresentano il totale dei premi versati su ciascun fondo al termine del programma periodico.";
         
        }
        public virtual string getNotaSKS()
        {
            return ") Programma periodico che prevede l’investimento iniziale nel portafoglio monetario “In Prima Persona – Linea Liquidità”. Gli apporti indicati rappresentano il totale dei premi versati su ciascun fondo al termine del programma periodico.";

        }
        public virtual string getNotaSKE()
        {
            return ") Programma periodico che prevede l’investimento iniziale nel portafoglio monetario “In Persona – Linea Liquidità”. Gli apporti indicati rappresentano il totale dei premi versati su ciascun fondo al termine del programma periodico.";

        }
    }
}
