Example #1
0
        /// <summary>
        /// Crea un dettaglio di sollecito valido.
        /// </summary>
        public DettaglioSollecito(Sollecito sollecito, decimal importoRata, decimal importoDaVersare, decimal importoPagato)
        {
            Sollecito = sollecito;
            ImportoRata = importoRata;
            ImportoDaVersare = importoDaVersare;
            ImportoPagato = importoPagato;

            if (Sollecito != null)
                Sollecito.Dettaglio.Add(this);
        }
Example #2
0
        public IList<TestataSollecitoDTO> GetSolleciti(int? idEsercizio, Dictionary<int, TipoIndirizzo> idCondomini, bool groupByPersone, DateTime? dataRate, DateTime? dataVersamenti, decimal? importoLimite, decimal? importoCompetenza, DateTime dataSollecito, bool stampaProprietario, int? idBanca, int idModelloLettera, string testoModelloLettera, DateTime? dataRegistrazioneContabile, int? idConto, int? idSottoConto, bool storico, bool sollecitaProprietarioConduzione)
        {
            try
            {
                var solleciti = new List<TestataSollecitoDTO>(idCondomini.Count);
                var listaSolleciti = new List<Sollecito>(idCondomini.Count);

                Esercizio esercizio = null;
                if (idEsercizio != null)
                    esercizio = _daoFactory.GetEsercizioDao().GetById(idEsercizio.Value, false);

                var dataFinale = new DateTime(DateTime.Today.Year, 12, 31);

                var modello = _daoFactory.GetModelloLetteraTestoDao().Find(idModelloLettera, false);

                // ==========================================================================================
                //  Leggo subito tutti i soggetti le rate e i versamenti
                // ==========================================================================================
                var idCondominiList = idCondomini.Select(item => item.Key).ToList();

                // rate
                var rateSoggetti = !groupByPersone ? _daoFactory.GetRataSoggettoDao().GetByEsercizioSoggetti(idEsercizio, null, idCondominiList, dataRate) : _daoFactory.GetRataSoggettoDao().GetByEsercizioPersone(idEsercizio, null, idCondominiList, dataRate);

                // soggetti
                IList<SoggettoCondominio> soggetti = null;
                IList<SoggettoCondominio> soggettiStampa = null;
                IList<Persona> persone = null;
                if (!groupByPersone)
                    soggetti = _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizioSoggetti(esercizio, idCondominiList);
                else
                {
                    persone = _daoFactory.GetPersonaDao().GetAttiviByEsercizioSoggetti(esercizio, idCondominiList);
                    soggettiStampa = esercizio != null ? _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizio(esercizio, dataFinale) : _daoFactory.GetSoggettoCondominioDao().GetAttiviByAzienda(modello.Azienda.ID);
                }

                // versamenti
                IList<VersamentoSoggetto> versamentiSoggetto;
                IList<VersamentiRate> versamentiRate;
                if (!groupByPersone)
                {
                    versamentiSoggetto = _daoFactory.GetVersamentoSoggettoDao().GetByEsercizioSoggetti(idEsercizio, idCondominiList);
                    versamentiRate = _daoFactory.GetVersamentiRateDao().GetByEsercizioSoggetti(idEsercizio, idCondominiList);
                }
                else
                {
                    versamentiSoggetto = _daoFactory.GetVersamentoSoggettoDao().GetByEsercizioPersone(idEsercizio, idCondominiList);
                    versamentiRate = _daoFactory.GetVersamentiRateDao().GetByEsercizioPersone(idEsercizio, idCondominiList);
                }

                DatiBancariCondomini bancaSollecito = null;
                if (idBanca != null)
                    bancaSollecito = _daoFactory.GetDatiBancariCondominiDao().Find(idBanca.Value, false);

                // ==========================================================================================
                //  Loop per i soggetti per generare i dati di stampa
                // ==========================================================================================
                foreach (var kvp in idCondomini)
                {
                    var id = kvp.Key;

                    try
                    {
                        SoggettoCondominio soggetto = null;
                        Persona persona = null;
                        if (soggetti != null)
                            soggetto = soggetti.FirstOrDefault(item => item.ID == kvp.Key) ?? _daoFactory.GetSoggettoCondominioDao().Find(id, false);
                        else if (persone != null)
                            persona = persone.FirstOrDefault(item => item.ID == kvp.Key) ?? _daoFactory.GetPersonaDao().Find(id, false);

                        if (persona == null && soggetto == null)
                        {
                            _log.ErrorFormat("Non trovata persona/soggetto - {0} - id:{1} - idCondomini:{2}", Utility.GetMethodDescription(), id, idEsercizio.GetValueOrDefault(), idCondomini != null ? string.Join(",", idCondomini.SelectMany(item => item.Key.ToString())) : "<NULL>");
                            continue;
                        }

                        var rateScadute = !groupByPersone ? rateSoggetti.Where(item => item.Soggetto.ID == kvp.Key).ToList() : rateSoggetti.Where(item => item.Soggetto.Persona.ID == kvp.Key).ToList();

                        // -----------------------------
                        // Calcolo importi
                        // -----------------------------
                        var importoScaduto = rateScadute.Sum(rata => rata.Importo);
                        var importoVersato = rateScadute.Sum(rata => rata.GetImportoVersato(dataVersamenti));

                        decimal importoVersatoSenzaRata;
                        IList<VersamentoSoggetto> altriVersamenti;
                        IList<VersamentiRate> altriVersamentiRate;
                        if (soggetto != null)
                        {
                            altriVersamenti = versamentiSoggetto.Where(item => item.Soggetto.ID == kvp.Key).ToList();
                            altriVersamentiRate = versamentiRate.Where(item => item.Versamento.Soggetto.ID == kvp.Key).ToList();
                            importoVersatoSenzaRata = altriVersamenti.Sum(versamento => versamento.Importo) - altriVersamentiRate.Sum(item => item.Importo);
                        }
                        else
                        {
                            altriVersamenti = versamentiSoggetto.Where(item => item.Soggetto.Persona.ID == kvp.Key).ToList();
                            altriVersamentiRate = versamentiRate.Where(item => item.Versamento.Soggetto.Persona.ID == kvp.Key).ToList();
                            importoVersatoSenzaRata = altriVersamenti.Sum(versamento => versamento.Importo) - altriVersamentiRate.Sum(item => item.Importo);
                        }

                        var importoDaSollecitare = importoScaduto - importoVersato - importoVersatoSenzaRata;

                        if (importoLimite == null || Math.Abs(importoDaSollecitare) >= importoLimite.Value)
                        {
                            if (persona == null)
                                persona = soggetto.Persona;
                            var condominio = soggetto != null ? soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.CondominioRiferimento : persona.SoggettiCondominio.Select(item => item.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.CondominioRiferimento).FirstOrDefault();

                            var recapito = _personaService.GetRecapito(persona, kvp.Value);

                            if (bancaSollecito == null)
                                bancaSollecito = condominio.DatiBancariPrincipale;

                            var testata = new TestataSollecitoDTO
                            {
                                Nominativo = getNominativoPresso(persona, soggetto, recapito),
                                Indirizzo = recapito != null ? recapito.GetIndirizzoCompleto() : string.Empty,
                                Cap = recapito.Cap,
                                Comune = recapito.ComuneDisplayName,
                                Titolo = Decodifica.Instance.GetElement("TitoloPersona", persona.Titolo).Descrizione,
                                ImportoCompetenza = importoCompetenza,
                                DataLettera = dataSollecito,
                                DataRate = dataRate.GetValueOrDefault(),
                                StampaProprietario = stampaProprietario,
                                GroupByPersona = groupByPersone,
                                OggettoLettera = string.IsNullOrEmpty(modello.Oggetto) ? string.Empty : modello.Oggetto.Trim(),
                                TestoLettera = formattaTestoLettera(condominio, bancaSollecito, string.IsNullOrEmpty(testoModelloLettera) ? modello.Testo : testoModelloLettera.Trim()),
                            };

                            if (soggetto != null)
                            {
                                testata.Id = soggetto.ID;
                                testata.IdSoggettoCondominio = soggetto.ID;
                                testata.IdPersona = soggetto.Persona.ID;
                                testata.IdUnitaImmobiliare = soggetto.UnitaImmobiliare.ID;
                                testata.Interno = soggetto.UnitaImmobiliare.InternoCompleto;
                                testata.Piano = soggetto.UnitaImmobiliare.Piano;
                                testata.Ordine = soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                testata.DescrizioneUnitaImmobiliare = soggetto.UnitaImmobiliare.Descrizione;
                                testata.Subalterno = soggetto.UnitaImmobiliare.Subalterno;
                            }
                            else if (persona != null)
                            {
                                testata.Id = persona.ID;
                                testata.IdPersona = persona.ID;
                            }

                            var righeCondominio = condominio.IndirizzoCompleto.Split('&');
                            testata.DescrizioneCompletaCondominio = $"Condominio: {righeCondominio[0]}{Environment.NewLine}{righeCondominio[1]} - {righeCondominio[2]} - {righeCondominio[3]}";

                            // Se la stampa è per persona e viee richiesta la stampa per conoscenza al proprietario occorre leggere il soggettocondominio (soggettoStampa) bugid#8573
                            var soggettoStampa = soggetto;
                            if (soggettoStampa == null && persona != null)
                                soggettoStampa = soggettiStampa.Where(item => item.Persona.ID == persona.ID).OrderBy(item => item.UnitaImmobiliare.TipoUnitaImmobiliare.ID).FirstOrDefault();

                            if (stampaProprietario && soggettoStampa != null && soggettoStampa.Tipo == TipoSoggetto.Conduttore)
                            {
                                var proprietario = soggettoStampa.UnitaImmobiliare.GetProprietarioPrincipale(dataFinale) ??
                                                   soggettoStampa.UnitaImmobiliare.Proprietari.OrderByDescending(item => item.DataInizio.GetValueOrDefault()).FirstOrDefault();
                                if (proprietario != null)
                                    testata.NominativoProprietario = proprietario.DisplayName;

                                if (proprietario != null)
                                {
                                    var recapitoProprietario = _personaService.GetRecapito(proprietario.Persona, kvp.Value);
                                    if (recapitoProprietario != null)
                                    {
                                        testata.IndirizzoProprietario = recapitoProprietario.GetIndirizzoCompleto();
                                        testata.ComuneProprietario = recapitoProprietario.ComuneDisplayName;
                                        testata.CapProprietario = recapitoProprietario.Cap;
                                    }
                                }
                            }

                            if (recapito.Comune != null)
                                testata.Provincia = recapito.Comune.ProvinciaAppartenenza.Codice;

                            // ----------------------------------------------
                            //  Dettaglio Rate
                            // ----------------------------------------------
                            decimal importoTotaleDaVersare = 0;

                            // Rate con versamenti
                            foreach (var rata in rateScadute)
                            {
                                try
                                {
                                    var dettaglio = new DettaglioSollecitoDTO
                                    {
                                        Id = rata.ID,
                                        DataScadenza = rata.DataScadenza,
                                        IdTestataSollecito = testata.Id,
                                        ProgressivoRata = rata.PianoRatealeDettaglio?.Progressivo ?? rata.Progressivo,
                                        Importo = rata.Importo,
                                        ImportoPagato = rata.GetImportoVersato(dataVersamenti),
                                        CodiceRata = rata.ID,
                                        IdEsercizio = rata.Esercizio.ID,
                                        IdSoggetto = rata.Soggetto.ID,
                                        DescrizioneSoggetto = rata.Soggetto.DisplayName,
                                        DescrizioneEsercizio = rata.Esercizio.DisplayName
                                    };

                                    if (groupByPersone)
                                    {
                                        dettaglio.IdUnitaImmobiliare = rata.Soggetto.UnitaImmobiliare.ID;
                                        dettaglio.Interno = rata.Soggetto.UnitaImmobiliare.InternoCompleto;
                                        dettaglio.Piano = rata.Soggetto.UnitaImmobiliare.Piano;
                                        dettaglio.Ordine = rata.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                        dettaglio.DescrizioneUnitaImmobiliare = rata.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + rata.Soggetto.UnitaImmobiliare.Descrizione;
                                        dettaglio.Subalterno = rata.Soggetto.UnitaImmobiliare.Subalterno;
                                    }

                                    if (soggetto?.PercentualeRiferimento != null)
                                        dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);
                                    dettaglio.ImportoDaVersare = dettaglio.Importo - dettaglio.ImportoPagato;

                                    if (rata.Versamenti.Count > 0)
                                        dettaglio.DataUltimoPagamento = IesiGenericCollections<VersamentiRate>.GetByIndex(rata.Versamenti, rata.Versamenti.Count - 1).Versamento.Data;

                                    testata.Dettagli.Add(dettaglio);
                                    importoTotaleDaVersare += dettaglio.ImportoDaVersare;
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - DETTAGLIO RATE CON VERSAMENTI - {0} - soggetto:{1} - rata:{2}", ex, Utility.GetMethodDescription(), id, rata.ID);
                                    throw;
                                }
                            }

                            // Versamenti senza rate associate
                            // TODO: elaborare versamenti rate e versamentisoggetto per ottenere una lista dei versamenti fuori piano rateale
                            foreach (var versamento in altriVersamenti)
                            {
                                try
                                {
                                    var versamento1 = versamento;
                                    var importoPagato = versamento.Importo - altriVersamentiRate.Where(item => item.Versamento.ID == versamento1.ID).Sum(item => item.Importo);
                                    if (importoPagato > 0)
                                    {
                                        var dettaglio = new DettaglioSollecitoDTO
                                        {
                                            DataScadenza = DateTime.MaxValue,
                                            DataUltimoPagamento = versamento.Data,
                                            IdTestataSollecito = testata.Id,
                                            ImportoPagato = importoPagato,
                                            IdEsercizio = versamento.Esercizio.ID,
                                            IdSoggetto = versamento.Soggetto.ID,
                                            DescrizioneSoggetto = versamento.Soggetto.DisplayName,
                                            DescrizioneEsercizio = versamento.Esercizio.DisplayName,
                                            ImportoDaVersare = importoPagato * -1
                                        };

                                        if (groupByPersone)
                                        {
                                            dettaglio.IdUnitaImmobiliare = versamento.Soggetto.UnitaImmobiliare.ID;
                                            dettaglio.Interno = versamento.Soggetto.UnitaImmobiliare.InternoCompleto;
                                            dettaglio.Piano = versamento.Soggetto.UnitaImmobiliare.Piano;
                                            dettaglio.Ordine = versamento.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                            dettaglio.DescrizioneUnitaImmobiliare = versamento.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + versamento.Soggetto.UnitaImmobiliare.Descrizione;
                                            dettaglio.Subalterno = versamento.Soggetto.UnitaImmobiliare.Subalterno;
                                        }

                                        if (soggetto?.PercentualeRiferimento != null)
                                            dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);

                                        testata.Dettagli.Add(dettaglio);
                                        importoTotaleDaVersare -= dettaglio.ImportoPagato;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - VERSAMENTO SENZA RATE ASSOCIATE - {0} - Id:{1} - versamento:{2}", ex, Utility.GetMethodDescription(), id, versamento.ID);
                                    throw;
                                }
                            }

                            testata.ImportoTotaleDaVersare = importoTotaleDaVersare;
                            testata.TipoIndirizzo = kvp.Value;
                            solleciti.Add(testata);
                            
                            // ================================================================================
                            //  Se richiesto aggiungo per i proprietari le rate di conduzione
                            // ================================================================================
                            if (sollecitaProprietarioConduzione)
                            {
                                if (soggetto != null)
                                {
                                    var conduttori = soggetto.UnitaImmobiliare.Conduttori;
                                    if (conduttori.Count > 0)
                                    {
                                        var idConduttori = new List<int>(conduttori.Count);
                                        idConduttori.AddRange(conduttori.Select(soggettoCondominio => soggettoCondominio.ID));
                                        var rateConduttori = _rateService.GetRataByEsercizioSoggetti(idEsercizio, idConduttori, dataRate, false);
                                        var versamentiConduttori = _versamentiService.GetVersamentiByEsercizioSoggetti(idEsercizio, idConduttori);

                                        var importoCompetenzaConduzione = rateConduttori.Sum(item => item.Importo.GetValueOrDefault());
                                        var importoVersatoConduzione = versamentiConduttori.Sum(item => item.Importo);
                                        testata.ImportoCompetenza += importoCompetenzaConduzione;
                                        testata.ImportoTotaleDaVersare += (importoCompetenzaConduzione - importoVersatoConduzione);

                                        // Dettaglio rate
                                        IList<VersamentoSoggetto> versamentiElaborati = new List<VersamentoSoggetto>();
                                        foreach (var rataSoggettoDTO in rateConduttori)
                                        {
                                            var dettaglio = new DettaglioSollecitoDTO
                                            {
                                                Id = rataSoggettoDTO.ID,
                                                DataScadenza = rataSoggettoDTO.DataScadenza,
                                                IdTestataSollecito = testata.Id,
                                                ProgressivoRata = rataSoggettoDTO.Progressivo,
                                                Importo = rataSoggettoDTO.Importo.GetValueOrDefault(),
                                                ImportoPagato = rataSoggettoDTO.ImportoPagato.GetValueOrDefault(),
                                                CodiceRata = rataSoggettoDTO.ID,
                                                IdEsercizio = rataSoggettoDTO.IdEsercizio,
                                                IdSoggetto = rataSoggettoDTO.IdSoggettoCondominio,
                                                DescrizioneSoggetto = rataSoggettoDTO.DescrizioneSoggettoCondominio,
                                                DescrizioneEsercizio = rataSoggettoDTO.DescrizioneEsercizio
                                            };

                                            if (groupByPersone)
                                            {
                                                dettaglio.IdUnitaImmobiliare = rataSoggettoDTO.IdUnitaImmobiliare;
                                                dettaglio.Ordine = rataSoggettoDTO.OrdineUnitaImmobiliare;
                                                dettaglio.DescrizioneUnitaImmobiliare = rataSoggettoDTO.DescrizioneUnitaImmobiliare;
                                                dettaglio.Subalterno = rataSoggettoDTO.Subalterno;
                                            }

                                            if (soggetto?.PercentualeRiferimento != null)
                                                dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);
                                            dettaglio.ImportoDaVersare = dettaglio.Importo - dettaglio.ImportoPagato;

                                            var rata = _daoFactory.GetRataSoggettoDao().Find(rataSoggettoDTO.ID, false);
                                            if (rata != null && rata.Versamenti.Count > 0)
                                            {
                                                foreach (var rateVersamenti in rata.Versamenti)
                                                    versamentiElaborati.Add(rateVersamenti.Versamento);

                                                dettaglio.DataUltimoPagamento = IesiGenericCollections<VersamentiRate>.GetByIndex(rata.Versamenti, rata.Versamenti.Count - 1).Versamento.Data;
                                            }

                                            testata.Dettagli.Add(dettaglio);
                                        }
                                        
                                        // Versamenti fuori piano rateale
                                        foreach (var versamentoSoggetto in versamentiConduttori)
                                        {
                                            if (!versamentiElaborati.Contains(versamentoSoggetto) && versamentoSoggetto.Importo > 0)
                                            {
                                                var dettaglioVersamento = new DettaglioSollecitoDTO
                                                {
                                                    DataScadenza = DateTime.MaxValue,
                                                    DataUltimoPagamento = versamentoSoggetto.Data,
                                                    IdTestataSollecito = testata.Id,
                                                    ImportoPagato = versamentoSoggetto.Importo,
                                                    IdEsercizio = versamentoSoggetto.Esercizio.ID,
                                                    IdSoggetto = versamentoSoggetto.Soggetto.ID,
                                                    DescrizioneSoggetto = versamentoSoggetto.Soggetto.DisplayName,
                                                    DescrizioneEsercizio = versamentoSoggetto.Esercizio.DisplayName,
                                                    ImportoDaVersare = versamentoSoggetto.Importo * -1
                                                };

                                                if (groupByPersone)
                                                {
                                                    dettaglioVersamento.IdUnitaImmobiliare = versamentoSoggetto.Soggetto.UnitaImmobiliare.ID;
                                                    dettaglioVersamento.Interno = versamentoSoggetto.Soggetto.UnitaImmobiliare.InternoCompleto;
                                                    dettaglioVersamento.Piano = versamentoSoggetto.Soggetto.UnitaImmobiliare.Piano;
                                                    dettaglioVersamento.Ordine = versamentoSoggetto.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                                    dettaglioVersamento.DescrizioneUnitaImmobiliare = versamentoSoggetto.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + versamentoSoggetto.Soggetto.UnitaImmobiliare.Descrizione;
                                                    dettaglioVersamento.Subalterno = versamentoSoggetto.Soggetto.UnitaImmobiliare.Subalterno;
                                                }

                                                testata.Dettagli.Add(dettaglioVersamento);
                                            }
                                        }
                                    }

                                }
                            }

                            // ================================================================
                            // Creo gli oggetti sollecito se richiesto
                            // ================================================================
                            if (storico)
                            {
                                var esercizioSollecito = (esercizio ?? _daoFactory.GetEsercizioDao().GetEsercizioCompetenza(condominio, DateTime.Today)) ?? _esercizioService.GetUltimoEsercizioOrdinario(condominio.ID);
                                if (esercizioSollecito != null)
                                {
                                    Sollecito sollecito;

                                    var testoLettera = testoModelloLettera;
                                    if (string.IsNullOrEmpty(testoLettera))
                                        testoLettera = modello.Testo;
                                    if (!string.IsNullOrEmpty(testoLettera))
                                        testoLettera = testoLettera.Trim();
                                    if (soggetto != null)
                                    {
                                        sollecito = new Sollecito(esercizioSollecito, soggetto, dataSollecito, dataRate.GetValueOrDefault(), importoLimite.GetValueOrDefault(), testata.ImportoTotaleDaVersare, bancaSollecito, modello.Oggetto, testoLettera)
                                        {
                                            ImportoCompetenza = importoCompetenza,
                                            TipoIndirizzo = kvp.Value,
                                            StampaProprietario = stampaProprietario,
                                            GroupByPersona = groupByPersone
                                        };
                                    }
                                    else
                                    {
                                        sollecito = new Sollecito(esercizioSollecito, persona, dataSollecito, dataRate.GetValueOrDefault(), importoLimite.GetValueOrDefault(), testata.ImportoTotaleDaVersare, bancaSollecito, modello.Oggetto, testoLettera)
                                        {
                                            ImportoCompetenza = importoCompetenza,
                                            TipoIndirizzo = kvp.Value,
                                            StampaProprietario = stampaProprietario,
                                            GroupByPersona = groupByPersone
                                        };
                                    }

                                    foreach (var dett in testata.Dettagli)
                                    {
                                        var dettaglio = new DettaglioSollecito(sollecito, dett.Importo, dett.ImportoDaVersare, dett.ImportoPagato)
                                        {
                                            DataUltimoPagamento = dett.DataUltimoPagamento
                                        };

                                        if (dett.DataScadenza != DateTime.MaxValue)
                                            dettaglio.DataScadenzaRata = dett.DataScadenza;

                                        if (dett.CodiceRata != null)
                                            dettaglio.Rata = rateSoggetti.FirstOrDefault(item => item.ID == dett.CodiceRata) ?? _daoFactory.GetRataSoggettoDao().GetById(dett.CodiceRata.Value, false);
                                    }
                                    listaSolleciti.Add(sollecito);
                                    _daoFactory.GetSollecitoDao().SaveOrUpdate(sollecito);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - {0} - esercizio:{1} - soggetto:{2}", ex, Utility.GetMethodDescription(), idEsercizio, id);
                        throw;
                    }
                }

                // ================================================================================================================
                // Rimuovo eventuali dettagli con importo a 0
                // ================================================================================================================
                foreach (var testataSollecitoDTO in solleciti)
                {
                    var dettagliDaRimuovere = testataSollecitoDTO.Dettagli.Where(dettaglioSollecitoDTO => dettaglioSollecitoDTO.Importo == 0 && dettaglioSollecitoDTO.ImportoDaVersare == 0 && dettaglioSollecitoDTO.ImportoPagato == 0).ToList();

                    foreach (var dettaglioSollecitoDTO in dettagliDaRimuovere)
                        testataSollecitoDTO.Dettagli.Remove(dettaglioSollecitoDTO);
                }

                // ================================================================================================================
                // Creo i movimenti di addebito - una testata per ogni Esercizio (possibile solo se è stato richiesto lo STORICO)
                // ================================================================================================================
                try
                {
                    if (importoCompetenza > 0)
                    {
                        var sollecitiPerEsercizio = listaSolleciti.GroupBy(item => item.Esercizio);

                        foreach (var sollecitiEsercizio in sollecitiPerEsercizio)
                        {
                            var esercizioAddebito = sollecitiEsercizio.Key;
                            Conto contoAddebito = null;
                            SottoConto sottoContoAddebito = null;
                            if (idConto != null)
                            {
                                contoAddebito = _daoFactory.GetContoDao().Find(idConto.Value, false);
                                if (idSottoConto != null)
                                    sottoContoAddebito = _daoFactory.GetSottoContoDao().GetById(idSottoConto.Value, false);
                            }
                            if (contoAddebito == null)
                            {
                                sottoContoAddebito = _daoFactory.GetSottoContoDao().GetAddebitoCompetenzeByEsercizio(esercizioAddebito.ID, esercizioAddebito.CondominioRiferimento.ID);
                                if (sottoContoAddebito != null)
                                    contoAddebito = sottoContoAddebito.ContoRiferimento;
                            }

                            if (contoAddebito != null && esercizioAddebito != null)
                            {
                                var testata = _movimentiContabileService.SetMovimentiSollecito(esercizioAddebito, sollecitiEsercizio.ToList(), dataRegistrazioneContabile.GetValueOrDefault(), contoAddebito, sottoContoAddebito);

                                // -------------------------------------------
                                // Genero il protocollo di archiviazione
                                // -------------------------------------------
                                var progressivo = _protocolloService.GetProgressivo(TipoProtocollo.Fattura, testata.EsercizioRiferimento.DataApertura.GetValueOrDefault().Year, testata.EsercizioRiferimento.CondominioRiferimento);
                                if (progressivo.Progressivo != null)
                                {
                                    testata.NumeroProtocollo = progressivo.Progressivo.Value;
                                    testata.AnnoArchiviazioneOttica = testata.EsercizioRiferimento.DataApertura.GetValueOrDefault().Year;
                                }
                                else
                                {
                                    _log.ErrorFormat("Errore imprevisto nella generazione del protocollo di archiviazione - {0} - esercizio:{1} - testata:{2} - message:{3}", Utility.GetMethodDescription(), esercizioAddebito.ID, testata.ID, progressivo.Message);
                                }

                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - CREAZIONE MOVIMENTI CONTABILI - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio);
                    throw;
                }

                return solleciti;

            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - CREAZIONE MOVIMENTI CONTABILI - {0} - esercizio:{1} - groupByPersone:{2} - dataRate:{3} - dataVersamenti:{4} - importoLimite:{5} - importoCompetenza:{6} - dataSollecito:{7} - stampaProprietario:{8} - idBanca:{9} - idModelloLettera:{10} - dataRegistrazioneContabile:{11} - idConto:{12} - idSottoConto:{13} - storico:{14} - esercizio:{15}", ex, Utility.GetMethodDescription(), idEsercizio.GetValueOrDefault(), groupByPersone, dataRate, dataVersamenti, importoLimite, importoCompetenza, dataSollecito, stampaProprietario, idBanca, idModelloLettera, dataRegistrazioneContabile, idConto, idSottoConto, storico, idEsercizio);
                throw;
            }

        }
        public string AnnullamentoMovimentoSollecito(Sollecito sollecito)
        {
            try
            {
                var message = string.Empty;
                if (sollecito.MovimentoEconomico != null)
                {
                    var movimento = sollecito.MovimentoEconomico;
                    if (movimento.Testata.EsercizioRiferimento.Stato == StatoEsercizioEnum.Aperto)
                    {
                        sollecito.MovimentoEconomico = null;

                        var movimentoContropartita = (from item in movimento.Testata.Movimenti
                                                        where item.NumeroRiga == 1
                                                        select item).SingleOrDefault();
                        if (movimentoContropartita != null)
                        {
                            movimentoContropartita.Importo = movimentoContropartita.GetImportoSenzaSegno() - movimento.GetImportoConSegno();
                            movimento.Testata.Movimenti.Remove(movimento);
                            movimento.Testata = null;
                            if (movimentoContropartita.GetImportoConSegno() == 0)
                                _daoFactory.GetTestataMovimentoContabileDao().Delete(movimentoContropartita.Testata);
                        }
                        else
                            message += "Non è stato trovato il movimento di contropartita" + Environment.NewLine;
                    }
                    else
                        message = "L'esercizio è chiuso non è ammesso l'annullamento delle competenze.";
                }
                else
                    message += "Il sollecito non ha competenze addebitate" + Environment.NewLine;

                return message;
            }
            catch (Exception ex)
            {
                
                _log.Fatal("Errore inaspettato nell'annullamento del movimento del sollecito - " + Utility.GetMethodDescription() + " - sollecito:" + sollecito.ID.ToString(), ex);
                throw;
            }
        }