public DataTable GetUnitaDataSourceByMovimento(string key, IRipartizioneSpesa movimento, Conto contoDetrazione)
        {
            try
            {
                DataTable table;

                DateTime dataRiferimento = DateTime.Today;
                var movimentoContabile = movimento as MovimentoContabile;
                if (movimentoContabile != null)
                    dataRiferimento = movimentoContabile.Testata.DataRegistrazione.GetValueOrDefault();

                if (key != null && _unitaSelezionate.ContainsKey(key))
                    table = _unitaSelezionate[key];
                else
                {
                    table = GetEmptyUnitaDataSource();

                    var conto = movimento.ContoRiferimento;
                    if (contoDetrazione != null)
                        conto = contoDetrazione;

                    if (conto.Ripartizione)
                    {
                        if (!conto.IsSpesePersonali)
                        {
                            var listaUnita = _daoFactory.GetUnitaImmobiliareDao().GetByCondominio(conto.CondominioRiferimento.ID);
                            foreach (var unita in listaUnita)
                            {
                                var row = table.NewRow();
                                row["IdUnitaImmobiliare"] = unita.ID;
                                row["Nominativo"] = unita.Descrizione;
                                if(unita.Ordine != null)
                                    row["Ordine"] = unita.Ordine;
                                row["Interno"] = unita.InternoCompleto;
                                row["TipoUnita"] = unita.TipoUnitaImmobiliare.Descrizione;
                                row["ParentId"] = unita.GruppoStabileRiferimento.ID;
                                row["ParentName"] = unita.GruppoStabileRiferimento.Descrizione;
                                row["Selezionato"] = !movimento.IsRipartoPersonalizzato && !conto.IsSpesePersonali && contoDetrazione == null;

                                var spesa = (from s in movimento.DettaglioRipartizione
                                             where s.UnitaRiferimento != null && s.UnitaRiferimento.ID == unita.ID
                                             select s).SingleOrDefault();

                                if (spesa != null)
                                {
                                    if (conto.IsSpesePersonali && spesa.Importo != null)
                                        row["Importo"] = spesa.Importo;
                                    if (spesa.Importo != null || movimento.IsRipartoPersonalizzato || contoDetrazione != null)
                                        row["Selezionato"] = true;
                                }

                                table.Rows.Add(row);
                            }
                        }
                        else
                        {
                            // Se conto è di spese personali il dettaglio della ripartizione deve sempre essere per soggetto mai per unità immobiliare
                            // La correzzione è necessaria per ragioni di compatibilità dopo il bugid#2926
                            foreach (var speseUnita in movimento.DettaglioRipartizione)
                            {
                                if (speseUnita.SoggettoCondominio == null && speseUnita.UnitaRiferimento != null)
                                {
                                    if (conto.PercentualeProprieta > 0)
                                        speseUnita.SoggettoCondominio = speseUnita.UnitaRiferimento.GetProprietarioPrincipale(dataRiferimento);
                                    else
                                    {
                                        var conduttore = speseUnita.UnitaRiferimento.GetConduttorePrincipale(dataRiferimento) ??
                                                         speseUnita.UnitaRiferimento.GetProprietarioPrincipale(dataRiferimento);
                                        speseUnita.SoggettoCondominio = conduttore;
                                    }

                                    speseUnita.UnitaRiferimento = null;
                                }
                            }

                            var soggetti = _daoFactory.GetSoggettoCondominioDao().GetAttiviByCondominioData(movimento.GetEsercizio().CondominioRiferimento.ID, null, null, movimento.GetEsercizio().DataApertura.GetValueOrDefault());
                            foreach (var soggetto in soggetti)
                            {
                                try
                                {
                                    var row = table.NewRow();
                                    row["IdSoggettoCondominio"] = soggetto.ID;
                                    row["Nominativo"] = soggetto.DisplayName;
                                    row["Interno"] = soggetto.UnitaImmobiliare.InternoCompleto;
                                    if (soggetto.UnitaImmobiliare.Ordine != null)
                                        row["Ordine"] = soggetto.UnitaImmobiliare.Ordine;
                                    row["TipoUnita"] = soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione;
                                    row["TipoCondomino"] = soggetto.Tipo.ToString();
                                    row["DirittiReali"] = soggetto.DirittoReale.GetValueOrDefault().Description();
                                    if(soggetto.PercentualeRiferimento != null)
                                       row["PercentualeSpese"] = soggetto.PercentualeRiferimento.GetValueOrDefault();
                                    row["Selezionato"] = false;
                                    row["ParentId"] = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.ID;
                                    row["ParentName"] = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.Descrizione;

                                    var spesa = (from s in movimento.DettaglioRipartizione
                                                 where s.SoggettoCondominio != null && s.SoggettoCondominio.ID == soggetto.ID
                                                 select s).SingleOrDefault();

                                    if (spesa != null)
                                    {
                                        if (conto.IsSpesePersonali && spesa.Importo != null)
                                            row["Importo"] = spesa.Importo;
                                        if (spesa.Importo != null || movimento.IsRipartoPersonalizzato || contoDetrazione != null)
                                            row["Selezionato"] = true;
                                    }

                                    table.Rows.Add(row);
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore nel calcolo del datasource delle ripartizioni spese (SINGOLO SOGGETTO) - {0} - soggetto:{1} - key:{2} - idMovimento:{3} ", ex, Utility.GetMethodDescription(), soggetto.ID,  key,  movimento.ID);
                                    throw;
                                }
                            }
                        }

                        table.AcceptChanges();
                    }
                }

                return table;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante la creazione del datasource per la ripartizione - {0} - key:{1} - movimento:{2}", ex, Utility.GetMethodDescription(), key, + movimento.ID);
                throw;
            }
        }
        public decimal GetImportoCompetenza(decimal? importo, GruppoStabile gruppo, IRipartizioneSpesa movimento, List<int> stabili, List<int> gruppi, TipoSoggetto tipoSoggetto, int? anno, int? detrazione)
        {
            if (importo == null)
                importo = movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault();

            if (gruppo == null)
                return GetImportoCompetenza(importo.GetValueOrDefault() * movimento.GetPercentualePagata(anno, detrazione), movimento, tipoSoggetto);

            var contoRiferimento = movimento.ContoRiferimento;

            if (gruppi == null && !string.IsNullOrEmpty(movimento.GruppiAddebito))
                gruppi = movimento.GruppiAddebito.Split('&').Select(int.Parse).ToList();

            var millesimiTotali = _millesimiService.GetByConto(contoRiferimento, null, gruppi, movimento.GetEsercizio());
            if (millesimiTotali.Count > 0)
            {
                var millesimi = _millesimiService.GetByConto(contoRiferimento, null, new List<int> { gruppo.ID }, movimento.GetEsercizio());
                var denominatore = millesimiTotali.Sum(item => item.Valore.GetValueOrDefault());
                if(denominatore != 0)
                    importo = importo.GetValueOrDefault() * millesimi.Sum(item => item.Valore.GetValueOrDefault()) / denominatore;
            }
            else
                importo = movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault();
            
            return GetImportoCompetenza(importo.GetValueOrDefault(), movimento, tipoSoggetto, anno, detrazione);
        }