/// <summary>
        /// Crea un dettaglio di Spedizione per Archiviazione Ottica valido
        /// </summary>
        public SpedizioneArchiviazioneOtticaDettaglio(SpedizioneArchiviazioneOttica testata, TestataMovimentoContabile testataMovimentoRiferimento)
        {
            Testata = testata;
            TestataMovimentoRiferimento = testataMovimentoRiferimento;

            if (Testata != null)
                Testata.Dettaglio.Add(this);
        }
 public TestataMovimentoContabileDTO GetByDomainEntity(TestataMovimentoContabile testata)
 {
     try
     {
         if (testata != null)
             return setDto(testata);
         throw new InvalidOperationException("Errore nel caricamento delle testate dei movimenti contabili: " + Library.Utility.GetMethodDescription() + ": La Testata è NULL.");
     }
     catch (Exception ex)
     {
         _log.ErrorFormat("Errore nel caricamento delle testate dei movimenti contabili - {0} - testata:{1}", ex, Library.Utility.GetMethodDescription(), testata != null ? testata.ID.ToString() : "<NULL>");
         throw;
     }
 }
Exemple #3
0
        /// <summary>
        /// Crea un movimento contabile valido.
        /// </summary>
        public MovimentoContabile(TestataMovimentoContabile testata, CausaleContabile causale, int? numeroRiga, SottoConto sottoConto, decimal? importo, string segno)
        {
            Causale = causale;
            NumeroRiga = numeroRiga;
            SottoContoRiferimento = sottoConto;
            ContoRiferimento = sottoConto.ContoRiferimento;
            Testata = testata;
            Importo = importo;
            Segno = segno;
            Stato = StatoMovimentoContabileEnum.Inserito;
            IsVisibileGestione = true;

            if (Testata != null)
            {
                Testata.Movimenti.Add(this);
                setNumeroRegistrazione();
            }
        }
Exemple #4
0
        private SpesaDTO convertTestataToDto(TestataMovimentoContabile item)
        {
            try
            {
                var daoFactory = _windsorRepository.GetDaoFactory(_info.Azienda);

                var movimentiNumeroUno = item.Movimenti.Where(mov => mov.NumeroRiga == 1).ToList();
                if(movimentiNumeroUno.Count > 1)
                    _log.WarnFormat("Trovato più di un movimento con numero riga 1 per una testata di movimento contabile - {0} - id:{1} - azienda:{2}", Utility.GetMethodDescription(), item.ID, _info.Azienda);

                var primoMovimento = movimentiNumeroUno.FirstOrDefault();
                var importo = item.GetImportoSpesa();

                var dto = new SpesaDTO
                {
                    IdEsercizio = item.EsercizioRiferimento.ID,
                    DescrizioneEsercizio = item.EsercizioRiferimento.DisplayName,
                    DescrizioneCondominio = item.EsercizioRiferimento.CondominioRiferimento.DisplayName,
                    IsAbilitataArchiviazioneOttica = item.IsAbilitataArchiviazioneOttica
                };

                if (item.SpesaRiferimento == null)
                {
                    if (primoMovimento != null && primoMovimento.FornitoreRiferimento != null)
                    {
                        dto.IdFornitore = primoMovimento.FornitoreRiferimento.ID;
                        dto.DisplayFornitore = primoMovimento.FornitoreRiferimento.DisplayName;
                    }
                }
                else
                {
                    dto.IdFornitore = item.SpesaRiferimento.FornitoreRiferimento.ID;
                    dto.DisplayFornitore = item.SpesaRiferimento.FornitoreRiferimento.DisplayName;
                    dto.NumeroDocumento = item.SpesaRiferimento.NumeroDocumento;
                    dto.DataDocumento = item.SpesaRiferimento.DataDocumento;
                }

                dto.IdTestata = item.ID;
                if (importo != null)
                {
                    dto.Imponibile = importo.Value;
                    dto.ImportoLordo = importo.Value;
                }

                dto.TipoDocumento = "Movimento";
                
                dto.StatoSpesa = StatoSpesaEnum.Pagata;
                if (item.Movimenti.Any(mov => mov.Stato == StatoMovimentoContabileEnum.Evaso))
                    dto.StatoSpesa = StatoSpesaEnum.Evasa;

                dto.DisplayName = item.Descrizione;
                dto.IdentificativoArchiviazioneOttica = getArchiviazioneOtticaService().GetIdentificativoArchiviazione(item);
                dto.DataRegistrazione = item.DataRegistrazione.GetValueOrDefault();
                dto.IsRipartoPersonalizzato = item.Movimenti.Any(mov => mov.IsRipartoPersonalizzato);

                if (item.AddebitoCompetenze.Count > 0)
                {
                    var firstOrDefault = item.AddebitoCompetenze.FirstOrDefault();
                    if (firstOrDefault != null)
                        dto.IdAddebitoCompetenze = firstOrDefault.ID;
                }

                // ------------------------------------------
                // Nominativo Spesa Personale
                // ------------------------------------------
                var nominativoSpesaPersonale = string.Empty;
                var movimentiPersonali = from mov in item.Movimenti
                                         where mov.ContoRiferimento.IsSpesePersonali
                                         select mov;
                foreach (var mov in movimentiPersonali)
                {
                    foreach (var spesaUnita in mov.DettaglioRipartizione)
                    {
                        if (spesaUnita.Importo.GetValueOrDefault() != 0)
                        {
                            if (!string.IsNullOrEmpty(nominativoSpesaPersonale))
                            {
                                if (!nominativoSpesaPersonale.Contains("<br/>"))
                                    nominativoSpesaPersonale = "<b>" + nominativoSpesaPersonale + "</b><br/>";
                                else
                                    nominativoSpesaPersonale += "<br/>";
                            }

                            if (spesaUnita.UnitaRiferimento != null)
                            {
                                if (mov.ContoRiferimento.PercentualeProprieta == 1)
                                {
                                    var proprietario = spesaUnita.UnitaRiferimento.GetProprietarioPrincipale(item.EsercizioRiferimento.DataChiusura);
                                    if(proprietario != null)
                                        nominativoSpesaPersonale += proprietario.DisplayName;
                                }
                                else
                                {
                                    var conduttore = spesaUnita.UnitaRiferimento.GetConduttorePrincipale(item.EsercizioRiferimento.DataChiusura);
                                    if (conduttore != null)
                                        nominativoSpesaPersonale += conduttore.DisplayName;
                                    else
                                    {
                                        var proprietario = spesaUnita.UnitaRiferimento.GetProprietarioPrincipale(item.EsercizioRiferimento.DataChiusura);
                                        if(proprietario != null)
                                            nominativoSpesaPersonale += proprietario.DisplayName;
                                    }
                                }
                            }
                            else
                                nominativoSpesaPersonale += spesaUnita.SoggettoCondominio.DisplayName;
                        }
                    }
                }

                dto.NominativoSpesaPersonale = nominativoSpesaPersonale;

                // ------------------------------------------
                // Scale Addebito
                // ------------------------------------------
                var scaleElaborate = new List<int>();
                var movimenti = from itemScala in item.Movimenti
                                where !string.IsNullOrEmpty(itemScala.GruppiAddebito)
                                select itemScala;
                dto.ScaleAddebito = getScaleAddebito(movimenti, scaleElaborate, daoFactory);

                // ------------------------------------------
                // Conti - Sottoconti Addebito
                // ------------------------------------------
                var descrizioniConti = new List<string>();
                var descrizioniSottoConti = new List<string>();
                var movimentiConti = from itemConto in item.Movimenti
                                     select itemConto;
                var descrizioni = getContiSottocontiDettagliAddebito(movimentiConti, descrizioniConti, descrizioniSottoConti, null, true, false, item.EsercizioRiferimento);
                dto.DescrizioneBilancio = descrizioni[0];
                dto.DescrizioneSottoconto = descrizioni[1];

                return dto;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella creazione dell'istanza DTO per una testata di movimento contabile - {0} - id:{1}", ex, Utility.GetMethodDescription(), item.ID);
                throw;
            }

        }
        public string IsAllowDeleteTestata(TestataMovimentoContabile testata)
        {
            var message = new StringBuilder();

            if (testata.EsercizioRiferimento.Stato == StatoEsercizioEnum.Chiuso)
                message.Append("La spesa è relativa ad un esercizio chiuso." + Environment.NewLine);

            if (testata.MovimentiEvasione.Count > 0)
                message.Append("La spesa è associata ad un altro movimento. Occorre eliminare prima il movimento dipendente." + Environment.NewLine);

            // Documenti inviati per archiviazione
            if (testata.SpedizioniArchiviazioneOttica.Count > 0)
            {
                var descrizioneSpese = string.Empty;
                foreach (var dettaglio in testata.SpedizioniArchiviazioneOttica)
                {
                    if (dettaglio.SpesaRiferimento != null)
                    {
                        descrizioneSpese += string.Format("{0} Ft. n.{1} del {2:d} - Forn.{3}{4}", 
                            _archiviazioneOtticaService.GetIdentificativoArchiviazione(dettaglio.SpesaRiferimento, true),
                            dettaglio.SpesaRiferimento.NumeroDocumento, 
                            dettaglio.SpesaRiferimento.DataDocumento.GetValueOrDefault(),
                            dettaglio.SpesaRiferimento.FornitoreRiferimento.DisplayName, 
                            Environment.NewLine);
                    }
                    else if(dettaglio.TestataMovimentoRiferimento != null)
                    {
                        descrizioneSpese += string.Format("{0} Mov.:{1} del {2:d}", _archiviazioneOtticaService.GetIdentificativoArchiviazione(dettaglio.TestataMovimentoRiferimento), dettaglio.TestataMovimentoRiferimento.Descrizione, dettaglio.TestataMovimentoRiferimento.DataRegistrazione.GetValueOrDefault());
                    }
                }

                message.Append("Alla spesa è associato un documento che è già stato spedito per l'archiviazione ottica. Verificare le seguenti fatture:" + Environment.NewLine + descrizioneSpese);
            }

            // Solleciti associati
            var solleciti = _daoFactory.GetSollecitoDao().GetByTestataMovimentoContabile(testata.ID);
            if (solleciti.Count > 0)
            {
                var descrizioneSolleciti = Environment.NewLine;
                foreach (var sollecito in solleciti)
                {
                    if (sollecito != null)
                    {
                        try
                        {
                            if (sollecito.Soggetto != null)
                                descrizioneSolleciti = string.Format("{0} - Sollecito di {1}{2}", descrizioneSolleciti, sollecito.Soggetto.DisplayName, Environment.NewLine);
                        }
                        catch (Exception ex)
                        {
                            _log.ErrorFormat("Errore inaspettato nella funzione - {0} - sollecito:{1}", ex, Utility.GetMethodDescription(), sollecito.ID);
                            throw;
                        }
                    }
                }
                message.Append("Alla spesa sono associati " + solleciti.Count + " solleciti con addebito di spese, il movimento sarà automaticamente annullato se sono annullati gli addebiti dalla lista solleciti:" + Environment.NewLine + descrizioneSolleciti + Environment.NewLine);
            }

            return message.ToString();
        }
        public TestataMovimentoContabile SetMovimentiInserimentoSpesa(Spesa spesa, TestataMovimentoContabile testata, DateTime dataRegistrazione)
        {
            var message = IsAllowDataRegistrazione(new List<int> {spesa.EsercizioRiferimento.CondominioRiferimento.ID}, spesa.EsercizioRiferimento, dataRegistrazione);

            if (message.Count == 0)
            {
                _daoFactory.GetSpesaDao().SaveOrUpdate(spesa);

                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IF");
                if (testata == null)
                    testata = new TestataMovimentoContabile(spesa.EsercizioRiferimento, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null);
                testata.SpesaRiferimento = spesa;
                _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                // ------------------------------------------------
                // Conto economico
                // ------------------------------------------------
                var numeroRiga = 0;
                var importoEconomico = 0m;
                foreach (var dettaglio in spesa.Dettagli)
                {
                    if (numeroRiga == 0)
                        testata.Descrizione = dettaglio.GetDescrizione();
                    foreach (var movimento in dettaglio.Movimenti)
                    {
                        movimento.Testata = testata;
                        movimento.IsMovimentoEconomico = true;
                        testata.Movimenti.Add(movimento);
                        numeroRiga++;
                        movimento.NumeroRiga = numeroRiga;

                        if (movimento.Importo < 0)
                            _log.WarnFormat("Presente importo movimento con segno negativo - {0} - movimento:{1}", Utility.GetMethodDescription(), movimento.ID);

                        importoEconomico += Math.Round(movimento.GetImportoPerSpesa(true).GetValueOrDefault(), 2);
                        _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                    }
                }

                foreach (var movimento in spesa.MovimentiBollette)
                {
                    movimento.Testata = testata;
                    movimento.IsMovimentoEconomico = true;
                    testata.Movimenti.Add(movimento);
                    numeroRiga++;
                    movimento.NumeroRiga = numeroRiga;

                    if (movimento.GetImportoConSegno() < 0)
                    {
                        movimento.Segno = "A";
                        movimento.Importo = movimento.GetImportoConSegno()*-1;
                    }

                    importoEconomico += movimento.Importo.GetValueOrDefault();
                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                }

                // ------------------------------------------------
                // Debiti VS Fornitori
                // ------------------------------------------------
                var importoTotale = spesa.ImportoLordo + spesa.AltreSpeseEsenti.GetValueOrDefault();
                var importoTotaleArrotondato = Math.Round(importoTotale, 2);

                numeroRiga++;
                var segno = "A";
                if (importoTotale < 0)
                {
                    segno = "D";
                    importoTotaleArrotondato = importoTotaleArrotondato*-1;
                }
                var movimentoPatrimoniale = new MovimentoContabile(testata, spesa.FornitoreRiferimento, causale, numeroRiga, _daoFactory.GetContoDao().GetByCodice(spesa.EsercizioRiferimento.ID, spesa.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoFornitori()), importoTotaleArrotondato, segno)
                {
                    Descrizione = $"Fatt. n. {spesa.NumeroDocumento} del {spesa.DataDocumento.GetValueOrDefault():d}"
                };
                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoPatrimoniale);

                // ------------------------------------------------
                // Eventuale arrotondamento
                // ------------------------------------------------
                if (spesa.TipoDocumento == "NOTACC" || spesa.ImportoLordo < 0)
                    importoTotaleArrotondato = importoTotaleArrotondato*-1;
                setMovimentoArrotondamento(importoTotaleArrotondato, importoEconomico, numeroRiga, spesa, testata, causale, null);

                return testata;
            }

            var ex = new InvalidDataException($"La data di registrazione {dataRegistrazione:d} non è valida");
            _log.ErrorFormat("Data di registrazione non valida - {0} - data:{1} - spesa:{2} - dataRegistrazione:{3}", ex, Utility.GetMethodDescription(), dataRegistrazione, spesa.ID, dataRegistrazione);
            throw ex;
        }
 public void CalcolaNumeroRiga(TestataMovimentoContabile testata)
 {
     var firstOrDefault = testata.Movimenti.OrderByDescending(mov => mov.NumeroRiga).FirstOrDefault();
     if (firstOrDefault != null)
     {
         var ultimoNumeroRiga = firstOrDefault.NumeroRiga.GetValueOrDefault();
         foreach (var movimento in testata.Movimenti)
         {
             if (movimento.NumeroRiga == null || movimento.NumeroRiga == 0)
             {
                 ultimoNumeroRiga++;
                 movimento.NumeroRiga = ultimoNumeroRiga;
             }
         }
     }
 }
        public string SetTestataContabileGenerica(TestataMovimentoContabileGenericoDTO dto)
        {
            try
            {
                var message = string.Empty;
                var numeroRiga = 0;

                if (dto.IdEsercizio > 0)
                {
                    if (dto.Movimenti.Sum(mov => mov.ImportoDare.GetValueOrDefault()) !=
                        dto.Movimenti.Sum(mov => mov.ImportoAvere.GetValueOrDefault()))
                        message = "Il totale Dare:" + dto.Movimenti.Sum(mov => mov.ImportoDare.GetValueOrDefault()).ToString("c") + " non corrisponde col totale Avere:" + dto.Movimenti.Sum(mov => mov.ImportoAvere.GetValueOrDefault()).ToString("c") + Environment.NewLine;
                    else if (dto.DataRegistrazione == null)
                        message = "Deve essere definita la data di registrazione" + Environment.NewLine;
                    else
                    {
                        var esercizio = _daoFactory.GetEsercizioDao().Find(dto.IdEsercizio.GetValueOrDefault(), false);

                        if (esercizio != null && esercizio.Stato == StatoEsercizioEnum.Aperto)
                        {
                            // controllo data registrazione
                            var messageData = IsAllowDataRegistrazione(new List<int> {esercizio.CondominioRiferimento.ID}, esercizio, dto.DataRegistrazione.GetValueOrDefault());
                            if (messageData.Count > 0)
                            {
                                _log.WarnFormat("Data di registrazione non valida - {0} - data:{1} - esercizio:{2}", Utility.GetMethodDescription(), dto.DataRegistrazione.GetValueOrDefault(), esercizio.ID);
                                return messageData.Aggregate(message, (current, mess) => current + (mess + Environment.NewLine));
                            }

                            var causale = _daoFactory.GetCausaleContabileDao().GetById(dto.IdCausale, false);

                            var testata = _daoFactory.GetTestataMovimentoContabileDao().Find(dto.ID, false);
                            if (testata == null)
                            {
                                testata = new TestataMovimentoContabile(esercizio, dto.DataRegistrazione.Value, TipoTestataMovimentoContabileEnum.Manuale, null) {IsAllowUpdate = false};
                                _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                            }
                            else
                            {
                                // ----------------------------------------------------------
                                // Verifico che tutti i movimenti siano aggiornabili
                                // ----------------------------------------------------------
                                message = testata.Movimenti.Select(movimento => IsAllowUpdateMovimento(movimento.ID)).Where(messageMovimento => !string.IsNullOrEmpty(messageMovimento)).Aggregate(message, (current, messageMovimento) => current + string.Format("{0}{1}", messageMovimento, Environment.NewLine));
                                if (!string.IsNullOrEmpty(message))
                                    return message;
                                // ----------------------------------------------------------

                                testata.EsercizioRiferimento = esercizio;
                                testata.DataRegistrazione = dto.DataRegistrazione.Value;
                                testata.Movimenti.Clear();
                            }

                            testata.Descrizione = dto.Descrizione;
                            foreach (var movimentoDto in dto.Movimenti)
                            {
                                numeroRiga++;
                                var conto = _daoFactory.GetContoDao().GetById(movimentoDto.IdConto.GetValueOrDefault(), false);
                                string segno;
                                decimal importo;
                                if (movimentoDto.ImportoAvere > 0)
                                {
                                    importo = movimentoDto.ImportoAvere.GetValueOrDefault();
                                    segno = "A";
                                }
                                else
                                {
                                    importo = movimentoDto.ImportoDare.GetValueOrDefault();
                                    segno = "D";
                                }

                                var movimento = _daoFactory.GetMovimentoContabileDao().Find(movimentoDto.ID, false);
                                if (movimento == null)
                                {
                                    movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, importo, segno) {Descrizione = movimentoDto.Descrizione};
                                    if (movimentoDto.IdFornitore != null && movimentoDto.IdFornitore.GetValueOrDefault() > 0)
                                        movimento.FornitoreRiferimento = _daoFactory.GetFornitoreDao().GetById(movimentoDto.IdFornitore.Value, false);
                                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                                }
                                else
                                {
                                    movimento.Causale = causale;
                                    movimento.Segno = segno;
                                    movimento.Importo = importo;
                                    movimento.ContoRiferimento = conto;
                                    movimento.NumeroRiga = numeroRiga;
                                    movimento.Descrizione = movimentoDto.Descrizione;
                                    if (movimentoDto.IdFornitore != null && movimentoDto.IdFornitore.GetValueOrDefault() > 0)
                                        movimento.FornitoreRiferimento = _daoFactory.GetFornitoreDao().GetById(movimentoDto.IdFornitore.Value, false);
                                }

                                testata.Movimenti.Add(movimento);

                                if (movimentoDto.IdSottoConto != null)
                                {
                                    if (movimentoDto.IdSottoConto > 0)
                                    {
                                        var sottoConto = _daoFactory.GetSottoContoDao().GetById(movimentoDto.IdSottoConto.Value, false);
                                        movimento.SottoContoRiferimento = sottoConto;
                                    }
                                    else if (movimentoDto.IdSottoConto < 0)
                                    {
                                        if (movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoBancario())
                                        {
                                            var banca = _daoFactory.GetDatiBancariCondominiDao().Find(movimentoDto.IdSottoConto.Value*-1, false);
                                            if (banca != null)
                                                movimento.ContoCorrenteBancario = banca;
                                        }
                                        else if (movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoFornitori())
                                        {
                                            var fornitore = _daoFactory.GetFornitoreDao().Find(movimentoDto.IdSottoConto.Value*-1, false);
                                            if (fornitore != null)
                                                movimento.FornitoreRiferimento = fornitore;
                                        }
                                        else if (movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini() || movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoRateCondomini())
                                        {
                                            var soggetto = _daoFactory.GetSoggettoCondominioDao().Find(movimentoDto.IdSottoConto.Value*-1, false);
                                            if (soggetto != null)
                                                movimento.CondominoRiferimento = soggetto;
                                        }
                                    }
                                }
                            }

                            // Aggiorno l'importo dell'eventuale versamento associato
                            foreach (var movimentoContabile in testata.Movimenti)
                            {
                                var versamento = _daoFactory.GetVersamentoSoggettoDao().GetByMovimentoContabile(movimentoContabile);
                                if (versamento != null)
                                    versamento.Importo = movimentoContabile.Importo.GetValueOrDefault();
                            }
                        }
                        else
                        {
                            if (esercizio != null)
                                message += "La registrazione non è possibile perchè l'esercizio è chiuso." + Environment.NewLine;
                            else
                            {
                                message += "L'esercizio non è più presente nel database." + Environment.NewLine;
                                _log.WarnFormat("Tentativo di registrare una testata generica di movimento contabile per un esercizio inesistente - {0} - esercizio:{1} - testata:{2}", Utility.GetMethodDescription(),  dto.IdEsercizio, dto.ID);
                            }
                        }
                    }
                }
                return message;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante l'aggiornamento della testata generica di movimento contabile - {0}", Utility.GetMethodDescription(), ex);
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentiVersamentiDopoChiusura(Esercizio esercizioStraordinario)
        {
            try
            {
                TestataMovimentoContabile testata = null;
                var contoVersamentiCondomini = _daoFactory.GetContoDao().GetByCodice(esercizioStraordinario.ID, esercizioStraordinario.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoVersamentiCondomini());
                var movimenti = GetMovimentiByContiData(esercizioStraordinario.CondominioRiferimento.ID, esercizioStraordinario.DataChiusura.GetValueOrDefault().AddDays(1), DateTime.MaxValue, new List<int> { contoVersamentiCondomini.ID });

                if (movimenti.Any())
                {
                    testata = new TestataMovimentoContabile(esercizioStraordinario, esercizioStraordinario.DataChiusura, TipoTestataMovimentoContabileEnum.Automatica, null)
                    {
                        AperturaChiusuraConti = true,
                        Descrizione = "Versamento dopo data chiusura"
                    };
                    var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("VC");
                    var contoVersamentiDopoChiusura = _pianoContiService.GetContoVersamentiSuccessiviAllaChiusura(esercizioStraordinario);
                    var numeroRiga = 0;
                    foreach (var movimentoContabile in movimenti)
                    {
                        try
                        {
                            if (movimentoContabile.CondominoRiferimento != null)
                            {
                                var descrizione = string.Format("Versamento dopo data chiusura - {0} del {1}", movimentoContabile.CondominoRiferimento.DisplayName, movimentoContabile.Testata.DataRegistrazione.GetValueOrDefault().ToShortDateString());

                                numeroRiga++;
                                var movimentoVersamento = new MovimentoContabile(testata, causale, numeroRiga, movimentoContabile.ContoRiferimento, movimentoContabile.Importo, movimentoContabile.Segno);
                                movimentoVersamento.CondominoRiferimento = movimentoContabile.CondominoRiferimento;
                                movimentoVersamento.Descrizione = descrizione;

                                numeroRiga++;
                                var movimentoContoTemporaneo = new MovimentoContabile(testata, causale, numeroRiga, contoVersamentiDopoChiusura, movimentoContabile.Importo, invertiSegno(movimentoContabile.Segno));
                                movimentoContoTemporaneo.CondominoRiferimento = movimentoContabile.CondominoRiferimento;
                                movimentoContoTemporaneo.Descrizione = descrizione;

                                // Nella stessa testata del versamento originale aggiungo il movimento di chiusura del conto temporaneo
                                var numeroRigaChiusura = movimentoContabile.Testata.Movimenti.Max(item => item.NumeroRiga) + 1;
                                var movimentoVersamentoChiusura = new MovimentoContabile(movimentoContabile.Testata, causale, numeroRigaChiusura, movimentoContabile.ContoRiferimento, movimentoContabile.Importo, invertiSegno(movimentoContabile.Segno));
                                movimentoVersamentoChiusura.CondominoRiferimento = movimentoContabile.CondominoRiferimento;
                                movimentoVersamentoChiusura.Descrizione = descrizione;

                                numeroRigaChiusura++;
                                var movimentoContoTemporaneoChiusura = new MovimentoContabile(movimentoContabile.Testata, causale, numeroRigaChiusura, contoVersamentiDopoChiusura, movimentoContabile.Importo, movimentoContabile.Segno);
                                movimentoContoTemporaneoChiusura.CondominoRiferimento = movimentoContabile.CondominoRiferimento;
                                movimentoContoTemporaneoChiusura.Descrizione = descrizione;
                            }
                        }
                        catch (Exception ex)
                        {
                            _log.ErrorFormat("Errore inaspettato durante la registrazione dei movimenti per i versamenti eseguiti dopo la chiusura - SINGOLO MOVIMENTO - {0} - esercizio:{1} - movimento:{2}", ex, Utility.GetMethodDescription(), esercizioStraordinario.ID, movimentoContabile.ID);
                            throw;
                        }
                    }
                }

                return testata;
            }
            catch (Exception ex)
            {
                var idEsercizio = string.Empty;
                if (esercizioStraordinario != null)
                    idEsercizio = esercizioStraordinario.ID.ToString();

                _log.FatalFormat("Errore inaspettato durante la registrazione dei movimenti per i versamenti eseguiti dopo la chiusura - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio);
                throw;
            }
        }
        private void setMovimentoArrotondamento(decimal importoAvere, decimal importoDare, int numeroRiga, Spesa spesa, TestataMovimentoContabile testata, CausaleContabile causale, LogTransazione logTransazione)
        {
            if (importoAvere != importoDare)
            {
                var importoArrotondamento = importoAvere - importoDare;
                numeroRiga++;
                var segno = "D";
                if (importoArrotondamento < 0)
                {
                    segno = "A";
                    importoArrotondamento = importoArrotondamento * -1;
                }
                var contoArrotondamenti = _pianoContiService.GetContoArrotondamenti(testata.EsercizioRiferimento);
                _daoFactory.GetContoDao().SaveOrUpdate(contoArrotondamenti);

                var movimentoArrotondamento = new MovimentoContabile(testata, causale, numeroRiga, contoArrotondamenti, importoArrotondamento, segno)
                {
                    Descrizione = spesa != null ? string.Format("Arrotondamento Fatt. n. {0} del {1:d}", spesa.NumeroDocumento, spesa.DataDocumento.GetValueOrDefault()) : string.Format("Arrotondamento per {0}", testata.GetDescrizione())
                };

                if(logTransazione == null)
                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoArrotondamento);
            }
        }
        private void setMovimentoArrotondamento(TestataMovimentoContabile testata, CausaleContabile causale, LogTransazione logTransazione)
        {
            var importoDare = 0m;
            var importoAvere = 0m;
            foreach (var movimento in testata.Movimenti)
            {
                if (movimento.Segno == "D")
                    importoDare += movimento.Importo.GetValueOrDefault();
                else
                    importoAvere += movimento.Importo.GetValueOrDefault();
            }

            var differenza = importoAvere - importoDare;
            if (differenza != 0)
            {
                var numeroRiga = testata.Movimenti.Max(item => item.NumeroRiga.GetValueOrDefault()) + 1;
                setMovimentoArrotondamento(importoAvere, importoDare, numeroRiga, null, testata, causale, null);
            }
        }
 public void SetMovimentoArrotondamento(Spesa spesa, TestataMovimentoContabile testata, CausaleContabile causale, LogTransazione logTransazione)
 {
     var importoTotale = testata.Movimenti.Where(item => item.Segno == "A").Sum(item => Math.Round(item.Importo.GetValueOrDefault(), 2, MidpointRounding.AwayFromZero));
     var importoEconomico = testata.Movimenti.Where(item => item.Segno == "D").Sum(item => Math.Round(item.Importo.GetValueOrDefault(), 2, MidpointRounding.AwayFromZero));
     var numeroRiga = testata.Movimenti.Max(item => item.NumeroRiga.GetValueOrDefault()) + 1;
     setMovimentoArrotondamento(importoTotale, importoEconomico, numeroRiga, spesa, testata, causale, logTransazione);
 }
        public IList<MovimentoContabile> SetMovimentoBolletta(BollettaDTO bolletta, Spesa spesa, TestataMovimentoContabile testata, LogTransazione logTransazione, bool controlloDataRegistrazione)
        {
            try
            {
                IList<MovimentoContabile> movimentiEconomici = new List<MovimentoContabile>();

                CausaleContabile causale;
                if (spesa.Utenza != null && spesa.Utenza.RipartoLetture)
                    causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IA");
                else
                    causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IF");

                if (testata == null && spesa.TestateMovimenti.Count > 0)
                {
                    testata = spesa.TestateMovimenti.FirstOrDefault();
                    if (testata != null)
                    {
                        testata.EsercizioRiferimento = spesa.EsercizioRiferimento;
                        testata.DataRegistrazione = bolletta.DataRegistrazione;
                    }
                }

                var dataRegistrazione = DateTime.Today;
                if (bolletta.DataRegistrazione != null)
                    dataRegistrazione = bolletta.DataRegistrazione.GetValueOrDefault();

                if (testata == null)
                {
                    testata = new TestataMovimentoContabile(spesa.EsercizioRiferimento, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null) { SpesaRiferimento = spesa };
                    spesa.TestateMovimenti.Add(testata);
                    testata.IsAllowUpdate = false;
                    if(logTransazione == null)
                        _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                    else
                        testata.LogTransazione = logTransazione;
                }

                // controllo data registrazione
                IList<string> message = new List<string>();
                if(controlloDataRegistrazione)
                    message = IsAllowDataRegistrazione(new List<int> { spesa.EsercizioRiferimento.CondominioRiferimento.ID }, spesa.EsercizioRiferimento, testata.DataRegistrazione.GetValueOrDefault());
                if (message.Count > 0)
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", testata.DataRegistrazione.GetValueOrDefault()));
                    _log.ErrorFormat("Data di registrazione non valida - {0} - data:{1} - spesa:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), testata.DataRegistrazione.GetValueOrDefault(), spesa.ID, spesa.EsercizioRiferimento.ID);
                    throw ex;
                }

                testata.Descrizione = bolletta.Descrizione;
                testata.DataRegistrazione = dataRegistrazione;

                // -------------------------------------------
                // Elimino movimenti cancellati
                // -------------------------------------------
                foreach (var mov in testata.Movimenti.Where(item => item.NumeroRiga > 1).ToList())
                    DeleteSingoloMovimento(mov);

                // -------------------------------------------
                // Movimenti Economici
                // -------------------------------------------
                var numeroRiga = 1;
                var importoEconomico = 0m;
                foreach (var movimentoDto in bolletta.Movimenti)
                {
                    if (movimentoDto.IdConto != null)
                    {
                        var importo = Math.Round(movimentoDto.Importo.GetValueOrDefault(), 2);
                        importoEconomico += importo;

                        var segno = "D";
                        if (importo < 0)
                        {
                            segno = "A";
                            importo = importo * -1;
                        }

                        var movimento = _daoFactory.GetMovimentoContabileDao().Find(movimentoDto.ID, false);
                        numeroRiga++;
                        if (movimento != null)
                        {
                            movimento.ContoRiferimento = _daoFactory.GetContoDao().GetById(movimentoDto.IdConto.Value, false);
                            movimento.Segno = segno;
                            movimento.Importo = importo;
                            movimento.Causale = causale;
                        }
                        else
                        {
                            movimento = new MovimentoContabile(testata, spesa, causale, testata.Movimenti.Count + 1, _daoFactory.GetContoDao().GetById(movimentoDto.IdConto.Value, false), importo, segno);
                            if(logTransazione == null)
                                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                        }

                        movimento.IsMovimentoEconomico = true;
                        movimento.NumeroRiga = numeroRiga;
                        movimento.Descrizione = movimentoDto.Descrizione;
                        if (movimentoDto.IdSottoConto != null && movimentoDto.IdSottoConto > 0)
                            movimento.SottoContoRiferimento = _daoFactory.GetSottoContoDao().GetById(movimentoDto.IdSottoConto.Value, false);

                        movimentoDto.ID = movimento.ID;
                        movimentiEconomici.Add(movimento);
                    }
                    else
                    {
                        _log.ErrorFormat("Movimento senza conto associato - {0} - bolletta:{1}", Utility.GetMethodDescription(), bolletta.ID);
                        throw (new Exception("Movimento senza conto associato - " + Utility.GetMethodDescription() + " - idBolletta:" + bolletta.ID));
                    }
                }

                // ------------------------------------------------
                // Debiti VS Fornitori
                // ------------------------------------------------
                var causalePatrimoniale = _daoFactory.GetCausaleContabileDao().GetByCodice("IF");
                var importoTotale = spesa.ImportoBolletta.GetValueOrDefault();
                var importoPatrimoniale = importoTotale;

                var segnoPatrimoniale = "A";
                if (importoTotale < 0)
                {
                    segnoPatrimoniale = "D";
                    importoTotale = importoTotale * -1;
                }

                var movimentoPatrimoniale = (testata.Movimenti.Where(item => !item.IsMovimentoEconomico && !item.ContoRiferimento.IsArrotondamento)).FirstOrDefault();
                if (movimentoPatrimoniale == null)
                {
                    movimentoPatrimoniale = new MovimentoContabile(testata, spesa.FornitoreRiferimento, causalePatrimoniale, 1, _daoFactory.GetContoDao().GetByCodice(spesa.EsercizioRiferimento.ID, spesa.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoFornitori()), importoTotale, segnoPatrimoniale);
                    if(logTransazione == null)
                        _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoPatrimoniale);
                }
                else
                {
                    movimentoPatrimoniale.NumeroRiga = 1;
                    movimentoPatrimoniale.Importo = importoTotale;
                    movimentoPatrimoniale.Segno = segnoPatrimoniale;
                }

                movimentoPatrimoniale.Descrizione = $"Fatt. n. {spesa.NumeroDocumento} del {spesa.DataDocumento.GetValueOrDefault():d}";

                // ------------------------------------------------
                // Eventuale arrotondamento
                // ------------------------------------------------
                setMovimentoArrotondamento(importoPatrimoniale, importoEconomico, numeroRiga, spesa, testata, causale, logTransazione);

                return movimentiEconomici;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella creazione del movimento di registrazione delle bollette - {0} - bolletta:{1}", ex, Utility.GetMethodDescription(), bolletta.ID);
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentoSpesaPersonale(Esercizio esercizio, TestataMovimentoContabile testata, SoggettoCondominio soggetto, Conto conto, string descrizione, decimal importo, DateTime dataRegistrazione)
        {
            var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IA");
            if (testata == null)
            {
                testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null) {Descrizione = "Calcolo interessi di mora", IsAllowUpdate = true};
            }

            // controllo data registrazione
            var message = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, testata.DataRegistrazione.GetValueOrDefault());
            if (message.Count > 0)
            {
                var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", testata.DataRegistrazione.GetValueOrDefault()));
                _log.FatalFormat("Data di registrazione non valida - {0} - data:{1} - soggetto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), testata.DataRegistrazione.GetValueOrDefault(), soggetto.ID, esercizio.ID);
                throw ex;
            }

            var movimento = new MovimentoContabile(testata, causale, testata.Movimenti.Count() + 1, conto, importo, "D") {Descrizione = descrizione};
            switch (soggetto.Tipo)
            {
                case TipoSoggetto.Proprietario:
                    movimento.PercentualeProprieta = 1;
                    break;
                case TipoSoggetto.Conduttore:
                    movimento.PercentualeProprieta = 0;
                    break;
            }

            movimento.IsRipartoPersonalizzato = true;
            new SpeseUnita(importo, null, soggetto, movimento);

            _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

            return testata;
        }
        public MovimentoContabile SetMovimentoBancarioGenerico(DatiBancariCondomini banca, Esercizio esercizioRiferimento, SottoConto sottoconto, decimal importo, string descrizione, DateTime dataRegistrazione, CausaleContabile causale)
        {
            try
            {
                var message = IsAllowDataRegistrazione(new List<int> { esercizioRiferimento.CondominioRiferimento.ID }, esercizioRiferimento, dataRegistrazione);
                if (message.Count > 0)
                {
                    var ex = new InvalidDataException($"La data di registrazione {dataRegistrazione} non è valida");
                    _log.FatalFormat("Data di registrazione non valida - {0} - data:{1} - esercizio:{2}", ex,  Utility.GetMethodDescription(), dataRegistrazione, esercizioRiferimento.ID);
                    throw ex;
                }

                var testata = new TestataMovimentoContabile(esercizioRiferimento, dataRegistrazione, TipoTestataMovimentoContabileEnum.Manuale, null)
                {
                    Descrizione = descrizione,
                    IsAbilitataArchiviazioneOttica = false,
                    IsAllowUpdate = true
                };
                _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                // -------------------------------------------------
                // Segno Movimento
                // ------------------------------------------------
                string segnoContoEconomico = "D";
                if (importo > 0)
                    segnoContoEconomico = "A";
                else
                    importo = importo * -1;

                // ------------------------------------------------
                // Conto economico
                // ------------------------------------------------
                var movimentoContoEconomico = new MovimentoContabile(testata, causale, 1, sottoconto, importo, segnoContoEconomico) {Descrizione = descrizione};
                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoContoEconomico);
                _ripartizioneService.SalvaRipartizione(movimentoContoEconomico, esercizioRiferimento.CondominioRiferimento.ID);

                // ------------------------------------------------
                // BANCA
                // ------------------------------------------------
                var movimentoBancario = new MovimentoContabile(testata, causale, 2, _daoFactory.GetContoDao().GetByCodice(esercizioRiferimento.ID, esercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoBancario()), importo, invertiSegno(segnoContoEconomico))
                {
                    Descrizione = descrizione, 
                    Stato = StatoMovimentoContabileEnum.Evaso,
                    ContoCorrenteBancario = banca
                };
                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoBancario);

                return movimentoBancario;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella contabilizzazione di un movimento bancario - {0} - importo:{1} - descrizione:{2} - data registrazione:{3:d}", ex, Utility.GetMethodDescription(), importo, descrizione, dataRegistrazione);
                throw;
            }
        }
        public TestataMovimentoContabile ChiusuraContiPatrimoniali(Esercizio esercizio)
        {
            try
            {
                var testata = new TestataMovimentoContabile(esercizio, esercizio.DataChiusura, TipoTestataMovimentoContabileEnum.Automatica, null) {AperturaChiusuraConti = true};
                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("OC");
                var contoTransitorio = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, "998");

                // =======================================================================================
                //  Registro tutti movimenti di chiusura dei conti
                // =======================================================================================
                var index = 0;
                foreach (var conto in esercizio.CondominioRiferimento.Conti)
                {
                    if (conto.Tipo == TipoContoEconomicoEnum.Patrimoniale && conto.Codice != _pianoContiService.GetCodiceContoRateCondomini() && conto.Codice != "910")
                    {
                        try
                        {
                            // ================
                            // Conto Fornitori
                            // ================
                            if (conto.Codice == _pianoContiService.GetCodiceContoFornitori())
                            {
                                var saldi = getSaldoContoFornitori(esercizio.ID, conto.ID);

                                _log.DebugFormat("Chiusura conti - CONTO FORNITORI - {0} - esercizio:{1} - count:{2} - importo:{3}", Utility.GetMethodDescription(), esercizio.ID, saldi.Count, saldi.Sum(item => item.Value));
                                foreach (var kvp in saldi)
                                {
                                    try
                                    {
                                        if (kvp.Value != 0)
                                        {
                                            var saldo = kvp.Value;

                                            // ---------------------------------------------------------------------------------------
                                            //  Movimento di chiusura
                                            // ---------------------------------------------------------------------------------------
                                            _log.DebugFormat("Chiusura conti - SINGOLO FORNITORE - {0} - fornitore:{1} {2} - esercizio:{3} - importo:{4}", Utility.GetMethodDescription(), kvp.Key.ID, kvp.Key.DisplayName, esercizio.ID, saldo);

                                            index++;
                                            var segno = "D";
                                            if (saldo < 0)
                                            {
                                                segno = "A";
                                                saldo = saldo * -1;
                                            }

                                            new MovimentoContabile(testata, kvp.Key, causale, index, conto, saldo, segno)
                                            {
                                                FornitoreRiferimento = kvp.Key,
                                                Descrizione = string.Format("Chiusura conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, kvp.Key.DisplayName, esercizio.DisplayName),
                                                Stato = StatoMovimentoContabileEnum.Evaso
                                            };

                                            // ---------------------------------------------------------------------------------------
                                            //  Registro la contropartita in un conto transitorio
                                            // ---------------------------------------------------------------------------------------
                                            var saldoContropartita = kvp.Value;
                                            index++;
                                            segno = "A";
                                            if (saldoContropartita < 0)
                                            {
                                                segno = "D";
                                                saldoContropartita = saldoContropartita * -1;
                                            }
                                            index++;
                                            new MovimentoContabile(testata, causale, index, contoTransitorio, saldoContropartita, segno)
                                            {
                                                FornitoreRiferimento = kvp.Key,
                                                Stato = StatoMovimentoContabileEnum.Evaso,
                                                Descrizione = string.Format("Chiusura di bilancio - conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, kvp.Key.DisplayName, esercizio.DisplayName)
                                            };

                                        }

                                    }
                                    catch (Exception ex)
                                    {
                                        _log.FatalFormat("Errore inaspettato durante la chiusura dei conti patrimoniali - (SINGOLO FORNITORE) - {0} - fornitore:{1} - conto:{2} {3} - esercizio:{4}", ex, Utility.GetMethodDescription(), kvp.Key.ID, conto.ID, conto.Descrizione, esercizio.ID);
                                        throw;
                                    }
                                }
                            }

                            // ================
                            // Conto Banca
                            // ================
                            else if (conto.Codice == _pianoContiService.GetCodiceContoBancario())
                            {
                                var saldi = getSaldoContoBanca(esercizio.ID, conto.ID);

                                _log.DebugFormat("Chiusura conti - CONTO BANCA - {0} - esercizio:{1} - count:{2} - importo:{3}", Utility.GetMethodDescription(), esercizio.ID, saldi.Count, saldi.Sum(item => item.Value));
                                foreach (var kvp in saldi)
                                {
                                    try
                                    {
                                        if (kvp.Value != 0)
                                        {
                                            var saldo = kvp.Value;

                                            // ---------------------------------------------------------------------------------------
                                            //  Movimento di chiusura
                                            // ---------------------------------------------------------------------------------------
                                            _log.DebugFormat("Chiusura conti - SINGOLO FORNITORE - {0} - contoCorrente:{1} {2} - esercizio:{3} - importo:{4}", Utility.GetMethodDescription(), kvp.Key.ID, kvp.Key.DisplayName, esercizio.ID, saldo);

                                            index++;
                                            var segno = "D";
                                            if (saldo < 0)
                                            {
                                                segno = "A";
                                                saldo = saldo * -1;
                                            }

                                            new MovimentoContabile(testata, causale, index, conto, saldo, segno)
                                            {
                                                ContoCorrenteBancario = kvp.Key,
                                                Descrizione = string.Format("Chiusura conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, kvp.Key.DisplayName, esercizio.DisplayName),
                                                Stato = StatoMovimentoContabileEnum.Evaso
                                            };

                                            // ---------------------------------------------------------------------------------------
                                            //  Registro la contropartita in un conto transitorio
                                            // ---------------------------------------------------------------------------------------
                                            var saldoContropartita = kvp.Value;
                                            index++;
                                            segno = "A";
                                            if (saldoContropartita < 0)
                                            {
                                                segno = "D";
                                                saldoContropartita = saldoContropartita * -1;
                                            }
                                            index++;
                                            new MovimentoContabile(testata, causale, index, contoTransitorio, saldoContropartita, segno)
                                            {
                                                ContoCorrenteBancario = kvp.Key,
                                                Stato = StatoMovimentoContabileEnum.Evaso,
                                                Descrizione = string.Format("Chiusura di bilancio - conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, kvp.Key.DisplayName, esercizio.DisplayName)
                                            };

                                        }

                                    }
                                    catch (Exception ex)
                                    {
                                        _log.FatalFormat("Errore inaspettato durante la chiusura dei conti patrimoniali - (SINGOLO FORNITORE) - {0} - contoCorrente:{1} - conto:{2} {3} - esercizio:{4}", ex, Utility.GetMethodDescription(), kvp.Key.ID, conto.ID, conto.Descrizione, esercizio.ID);
                                        throw;
                                    }
                                }
                            }

                            // ================
                            // Conto Condomini
                            // ================
                            else if (conto.Codice == _pianoContiService.GetCodiceContoRateCondomini() || conto.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini())
                            {
                                var saldi = getSaldoContoCondomini(esercizio.ID, conto.ID);

                                _log.DebugFormat("Chiusura conti - CONTO CONDOMINI - {0} - esercizio:{1} - count:{2} - importo:{3}", Utility.GetMethodDescription(), esercizio.ID, saldi.Count, saldi.Sum(item => item.Value));
                                foreach (var kvp in saldi)
                                {
                                    try
                                    {
                                        if (kvp.Value != 0)
                                        {
                                            var saldo = kvp.Value;

                                            // ---------------------------------------------------------------------------------------
                                            //  Movimento di chiusura
                                            // ---------------------------------------------------------------------------------------
                                            SoggettoCondominio soggettoCondominio = null;
                                            var nomeCondomino = string.Empty;
                                            if (kvp.Key > 0)
                                            {
                                                soggettoCondominio = _daoFactory.GetSoggettoCondominioDao().GetById(kvp.Key, false);
                                                nomeCondomino = soggettoCondominio.DisplayName;
                                            }

                                            _log.DebugFormat("Chiusura conti - SINGOLO CONDOMINO - {0} - condomino:{1} {2} - esercizio:{3} - importo:{4}", Utility.GetMethodDescription(), kvp, nomeCondomino, esercizio.ID, saldo);
                                            
                                            var segno = "D";
                                            if (saldo < 0)
                                            {
                                                segno = "A";
                                                saldo = saldo * -1;
                                            }

                                            index++;
                                            new MovimentoContabile(testata, causale, index, conto, saldo, segno)
                                            {
                                                CondominoRiferimento = soggettoCondominio,
                                                Stato = StatoMovimentoContabileEnum.Evaso,
                                                Descrizione = string.Format("Chiusura conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, nomeCondomino, conto.EsercizioRiferimento == null ? esercizio.DisplayName : conto.EsercizioRiferimento.DisplayName),
                                            };

                                            // ---------------------------------------------------------------------------------------
                                            //  Registro la contropartita in un conto transitorio
                                            // ---------------------------------------------------------------------------------------
                                            var saldoContropartita = kvp.Value;
                                            index++;
                                            segno = "A";
                                            if (saldoContropartita < 0)
                                            {
                                                segno = "D";
                                                saldoContropartita = saldoContropartita * -1;
                                            }
                                            index++;
                                            new MovimentoContabile(testata, causale, index, contoTransitorio, saldoContropartita, segno)
                                            {
                                                CondominoRiferimento = soggettoCondominio,
                                                Stato = StatoMovimentoContabileEnum.Evaso,
                                                Descrizione = string.Format("Chiusura di bilancio - conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, nomeCondomino, esercizio.DisplayName)
                                            };
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        _log.FatalFormat("Errore inaspettato durante la chiusura dei conti patrimoniali - (SINGOLO CONDOMINO) - {0} - condomino:{1} - conto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), kvp.Key, conto.Descrizione,  esercizio.ID);
                                        throw;
                                    }

                                }
                            }
                            else
                            {
                                // ================
                                //  Altri Conti
                                // ================
                                var idConti = new List<int> { conto.ID };
                                var movimenti = GetMovimentiByContiData(esercizio.CondominioRiferimento.ID, esercizio.DataApertura.GetValueOrDefault(), esercizio.DataChiusura.GetValueOrDefault(), idConti);
                                var movimentiPerSottoconto = movimenti.GroupBy(item => item.SottoContoRiferimento);

                                foreach (var sottoconto in movimentiPerSottoconto)
                                {
                                    var saldo = sottoconto.Sum(item => item.GetImportoConSegno(false, true).GetValueOrDefault());
                                    var saldoContropartita = saldo;
                                    if (saldo != 0)
                                    {
                                        // ---------------------------------------------------------------------------------------
                                        //  Movimento di chiusura
                                        // ---------------------------------------------------------------------------------------
                                        var idSottoconto = "<NULL>";
                                        var descrizioneSottoconto = "<NULL>";
                                        if (sottoconto.Key != null)
                                        {
                                            idSottoconto = sottoconto.Key.ID.ToString();
                                            descrizioneSottoconto = sottoconto.Key.Descrizione;
                                        }

                                        _log.DebugFormat("Chiusura conti - SINGOLO SOTTOCONTO - {0} - sottconto:{1} {2} - esercizio:{3} - importo:{4}", Utility.GetMethodDescription(), idSottoconto, descrizioneSottoconto, esercizio.ID, saldo);

                                        index++;
                                        var segno = "D";
                                        if (saldo < 0)
                                        {
                                            segno = "A";
                                            saldo = saldo * -1;
                                        }
                                        new MovimentoContabile(testata, causale, index, conto, saldo, segno)
                                        {
                                            SottoContoRiferimento = sottoconto.Key,
                                            Descrizione = sottoconto.Key != null ? string.Format("Chiusura conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, sottoconto.Key.Descrizione, esercizio.DisplayName) : string.Format("Chiusura conto {0} - Esercizio '{1}'", conto.Descrizione, esercizio.DisplayName),
                                            Stato = StatoMovimentoContabileEnum.Evaso
                                        };

                                        // ---------------------------------------------------------------------------------------
                                        //  Registro la contropartita in un conto transitorio
                                        // ---------------------------------------------------------------------------------------
                                        index++;
                                        segno = "A";
                                        if (saldoContropartita < 0)
                                        {
                                            segno = "D";
                                            saldoContropartita = saldoContropartita * -1;
                                        }
                                        index++;
                                        new MovimentoContabile(testata, causale, index, contoTransitorio, saldoContropartita, segno)
                                        {
                                            SottoContoRiferimento = sottoconto.Key,
                                            Stato = StatoMovimentoContabileEnum.Evaso,
                                            Descrizione = sottoconto.Key != null ? string.Format("Chiusura di bilancio '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, sottoconto.Key.Descrizione, esercizio.DisplayName) : string.Format("Chiusura di bilancio {0} - Esercizio '{1}'", conto.Descrizione, esercizio.DisplayName),
                                        };
                                    }
                                }

                            }
                        }
                        catch (Exception ex)
                        {
                            _log.FatalFormat("Errore inaspettato durante la chiusura dei conti patrimoniali - (SINGOLO CONTO) - {0} - conto:{1} {2} - esercizio:{3}", ex, Utility.GetMethodDescription(), conto.ID, conto.Descrizione, esercizio.ID);
                            throw;
                        }
                    }
                }

                // Solo se sono presenti movimenti
                if (testata.Movimenti.Count > 0)
                {
                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                    return testata;
                }

                return null;
            }
            catch (Exception ex)
            {
                _log.FatalFormat("Errore inaspettato durante la chiusura dei conti patrimoniali - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID);
                throw;
            }
        }
        public string AperturaContiPatrimoniali(Esercizio esercizio)
        {
            try
            {
                var message = string.Empty;

                if (esercizio.GetEsercizioPrecedente() != null)
                {
                    var testata = new TestataMovimentoContabile(esercizio, esercizio.DataApertura, TipoTestataMovimentoContabileEnum.Automatica, null) { AperturaChiusuraConti = true };
                    var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("AC");
                    var contoTransitorio = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, "999");

                    // ---------------------------------------------------------------------------------------
                    //  Registro tutti movimenti di apertura dei conti
                    // ---------------------------------------------------------------------------------------
                    var index = 0;
                    var testate = _daoFactory.GetTestataMovimentoContabileDao().GetTestateMovimentiByEsercizioCausale(esercizio.GetEsercizioPrecedente(), _daoFactory.GetCausaleContabileDao().GetByCodice("OC")).Where(item => item.AperturaChiusuraConti).ToList();
                    if (testate.Count > 1)
                    {
                        _log.ErrorFormat("ATTENZIONE: Trovata più di una testata con causale di chiusura 'OC' nell'esercizio - {0} - esercizio:{1}", Utility.GetMethodDescription(), esercizio.ID);
                        return string.Format("Trovata più di una testata di chiusura nell'esercizio: '{0}'", esercizio.DisplayName);
                    }
                    else if(testate.Count == 0)
                    {
                        _log.ErrorFormat("ATTENZIONE: Non è stata trovata nessuna causale di chiusura 'OC' nell'esercizio - {0} - esercizio:{1}", Utility.GetMethodDescription(), esercizio.ID);
                        return string.Format("Non è stata trovata nessuna testata di chiusura nell'esercizio: '{0}'", esercizio.DisplayName);
                    }
                    else
                    {
                        foreach (var movimento in testate[0].Movimenti)
                        {
                            var importo = movimento.GetImportoSenzaSegno();
                            index++;
                            if (movimento.ContoRiferimento.Codice != "998")
                            {
                                new MovimentoContabile(testata, causale, index, movimento.ContoRiferimento, importo, invertiSegno(movimento.Segno))
                                {
                                    Descrizione = movimento.Descrizione.Replace("Chiusura", "Apertura"),
                                    Stato = StatoMovimentoContabileEnum.Evaso,
                                    FornitoreRiferimento = movimento.FornitoreRiferimento,
                                    CondominoRiferimento = movimento.CondominoRiferimento,
                                    ContoCorrenteBancario = movimento.ContoCorrenteBancario,
                                    SottoContoRiferimento = movimento.SottoContoRiferimento
                                };
                            }
                            else
                            {
                                new MovimentoContabile(testata, causale, index, contoTransitorio, importo, invertiSegno(movimento.Segno))
                                {
                                    Descrizione = movimento.Descrizione.Replace("Chiusura", "Apertura"),
                                    Stato = StatoMovimentoContabileEnum.Evaso,
                                    FornitoreRiferimento = movimento.FornitoreRiferimento,
                                    CondominoRiferimento = movimento.CondominoRiferimento,
                                    ContoCorrenteBancario = movimento.ContoCorrenteBancario,
                                    SottoContoRiferimento = movimento.SottoContoRiferimento
                                };
                                
                            }
                        }

                        _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                    }

                }

                return message;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante l'apertura dei conti patrimoniali - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID);
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentiRiscaldamentoAcqua(Esercizio esercizio, int idContoAcquaRiscaldata, int idContoRiscaldamento, string descrizioneMovimentoAcqua, string descrizioneMovimentoRiscaldamento, IList<ImportiDTO> importiRiscaldamento, DateTime dataRegistrazione, bool checkDataRegistrazione)
        {
            // controllo data registrazione
            if (checkDataRegistrazione)
            {
            var message = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
                if (message.Count > 0)
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", dataRegistrazione));
                	_log.Fatal("Data di registrazione non valida - " + Utility.GetMethodDescription() + " - data:" + dataRegistrazione + " - IdEsercizio:" + esercizio.ID, ex);
                    throw ex;
                }
            }

            var testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null)
            {
                Descrizione = descrizioneMovimentoAcqua,
                IsAbilitataArchiviazioneOttica = false,
                IsAllowUpdate = true
            };
            _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

            var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("SC");

            // -------------------------------------------------
            // Calcolo Importo
            // ------------------------------------------------
            var importo = importiRiscaldamento.Sum(item => item.Importo);

            // -------------------------------------------------
            // Segno Movimento
            // ------------------------------------------------
            var segnoContoEconomico = "D";
            if (importo < 0)
            {
                segnoContoEconomico = "A";
                importo = importo * -1;
            }

            // ------------------------------------------------
            // Conto economico da addebitare
            // ------------------------------------------------
            var contoEconomico = _daoFactory.GetContoDao().GetById(idContoAcquaRiscaldata, false);
            var movimentoContoEconomicoAddebito = new MovimentoContabile(testata, causale, 1, contoEconomico, importo, segnoContoEconomico)
            {
                Descrizione = descrizioneMovimentoAcqua,
                IsRipartoPersonalizzato = true,
                RipartoTramiteLetture = true
            };
            _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoContoEconomicoAddebito);
            _ripartizioneService.SalvaRipartizione(movimentoContoEconomicoAddebito, importiRiscaldamento, false);

            // ------------------------------------------------
            // Conto economico da accreditare
            // ------------------------------------------------
            var movimentoContoEconomicoAccredito = new MovimentoContabile(testata, causale, 2, _daoFactory.GetContoDao().GetById(idContoRiscaldamento, false), importo, invertiSegno(segnoContoEconomico)) {Descrizione = descrizioneMovimentoRiscaldamento};
            _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoContoEconomicoAccredito);

            return testata;
        }
        public TestataResult SetBilancioApertura(TestataMovimentoContabileGestioneDTO testataDto)
        {
            try
            {
                if(testataDto.DataRegistrazione == null)
                    throw new InvalidDataException("Non è definita la data di registrazione");

                var message = string.Empty;
                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("AB");
                var numeroRiga = 0;

                var esercizio = _daoFactory.GetEsercizioDao().GetById(testataDto.CodiceEsercizio, false);
                var saldiCondomini = _daoFactory.GetSaldoSoggettoDao().GetByEsercizioStabileScala(esercizio, null, null);

                // Controllo correttezza importi
                TestataMovimentoContabile testata = null;
                if (testataDto.Movimenti.Sum(mov => mov.ImportoDare.GetValueOrDefault()) != testataDto.Movimenti.Sum(mov => mov.ImportoAvere.GetValueOrDefault()))
                    message = "Il totale Dare:" + testataDto.Movimenti.Sum(mov => mov.ImportoDare.GetValueOrDefault()).ToString("c") + " non corrisponde col totale Avere:" + testataDto.Movimenti.Sum(mov => mov.ImportoAvere.GetValueOrDefault()).ToString("c") + Environment.NewLine;
                else if (testataDto.DataRegistrazione == null)
                    message = "Deve essere definita la data di registrazione" + Environment.NewLine;
                else
                {
                    foreach (var movimentoDto in testataDto.Movimenti)
                    {
                        if (movimentoDto.Stato == "U")
                        {
                            var conto = _daoFactory.GetContoDao().GetById(movimentoDto.IdConto.GetValueOrDefault(), false);
                            if (conto.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini() && saldiCondomini.Count == 0)
                            {
                                message = "Prima di registrare il bilancio di apertura occorre inserire i saldi iniziali dei condomini" + Environment.NewLine;
                                break;
                            }
                        }
                    }
                }

                if(string.IsNullOrEmpty(message))
                {
                    // controllo data registrazione
                    var messageData = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, testataDto.DataRegistrazione.GetValueOrDefault());
                    if (messageData.Count > 0)
                    {
                        _log.WarnFormat("Data di registrazione non valida - {0} - data:{1} - esercizio:{2}", Utility.GetMethodDescription(), testataDto.DataRegistrazione.GetValueOrDefault(), esercizio.ID);
                        return new TestataResult(null, messageData.Aggregate(message, (current, mess) => current + (mess + Environment.NewLine)));
                    }

                    const string hql = "FROM Esercizio ES WHERE ES.CondominioRiferimento = :condominio AND ES.DataApertura >= :data AND ES.DataChiusura <= :data AND ES.Gestione = :gestione";
                    var listaEsercizi = _daoFactory.GetEsercizioDao().GetByQuery(hql, new[] { new QueryParam("condominio", esercizio.CondominioRiferimento), new QueryParam("data", testataDto.DataRegistrazione.Value), new QueryParam("gestione", Conversione.ToHQLParameter(GestioneEsercizioEnum.Ordinario)) });
                    if (listaEsercizi.Count == 1)
                        esercizio = listaEsercizi[0];

                    testata = _daoFactory.GetTestataMovimentoContabileDao().Find(testataDto.ID, false);
                    if (testata == null)
                    {
                        testata = new TestataMovimentoContabile(esercizio, testataDto.DataRegistrazione.Value, TipoTestataMovimentoContabileEnum.Automatica, null) {AperturaBilancio = true};
                        _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                    }
                    else
                    {
                        testata.EsercizioRiferimento = esercizio;
                        testata.DataRegistrazione = testataDto.DataRegistrazione.Value;
                    }

                    testata.Descrizione = testataDto.Descrizione;
                    foreach (var movimentoDto in testataDto.Movimenti)
                    {
                        if (movimentoDto.Stato == "U")
                        {
                            var conto = _daoFactory.GetContoDao().GetById(movimentoDto.IdConto.GetValueOrDefault(), false);
                            string segno;
                            decimal importo;
                            if (movimentoDto.ImportoAvere > 0)
                            {
                                importo = movimentoDto.ImportoAvere.GetValueOrDefault();
                                segno = "A";
                            }
                            else
                            {
                                importo = movimentoDto.ImportoDare.GetValueOrDefault();
                                segno = "D";
                            }
                            
                            // =========================================================================================
                            // Per il conto versamenti SOLO ESERCIZIO ORDINARIO spalmo l'importo in base ai versamenti dei singoli condomini
                            // Elimino tutti i movimenti presenti
                            // =========================================================================================
                            MovimentoContabile movimento = null;
                            if (conto.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini() && conto.EsercizioRiferimento == null)
                            {
                                // elimino i movimenti
                                var movimentiOld = testata.Movimenti.Where(item => item.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini()).ToList();
                                bool deleteOriginalMovimento = movimentoDto.ID > 0;
                                foreach (var movimentoContabile in movimentiOld)
                                {
                                    if (movimentoContabile.ID == movimentoDto.ID)
                                        deleteOriginalMovimento = false;
                                    DeleteSingoloMovimento(movimentoContabile);
                                }
                                if(deleteOriginalMovimento)
                                    DeleteSingoloMovimento(_daoFactory.GetMovimentoContabileDao().Find(movimentoDto.ID, false));

                                // creo i nuovi movimenti
                                foreach (var saldoSoggetto in saldiCondomini)
                                {
                                    var importoCondomino = saldoSoggetto.Importo;

                                    segno = "D";
                                    if (importoCondomino < 0)
                                    {
                                        segno = "A";
                                        importoCondomino = importoCondomino*-1;
                                    }
                                    numeroRiga++;
                                    movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, importoCondomino, segno) {Descrizione = movimentoDto.Descrizione};
                                    if (string.IsNullOrEmpty(movimento.Descrizione))
                                        movimento.Descrizione = string.Format("Apertura Conto {0}", saldoSoggetto.Soggetto.DisplayName);
                                    movimento.CondominoRiferimento = saldoSoggetto.Soggetto;
                                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                                    testata.Movimenti.Add(movimento);
                                }
                            }
                            else
                            {
                                movimento = _daoFactory.GetMovimentoContabileDao().Find(movimentoDto.ID, false);
                                if (movimento == null)
                                {
                                    numeroRiga++;
                                    movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, importo, segno) {Descrizione = movimentoDto.Descrizione};
                                    if (string.IsNullOrEmpty(movimento.Descrizione))
                                        movimento.Descrizione = "Apertura Conto";
                                    if (movimentoDto.IdFornitore != null && movimentoDto.IdFornitore.GetValueOrDefault() > 0)
                                        movimento.FornitoreRiferimento = _daoFactory.GetFornitoreDao().GetById(movimentoDto.IdFornitore.Value, false);
                                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimento);
                                    testata.Movimenti.Add(movimento);
                                }
                                else
                                {
                                    numeroRiga++;
                                    movimento.Segno = segno;
                                    movimento.Importo = importo;
                                    movimento.ContoRiferimento = conto;
                                    movimento.NumeroRiga = numeroRiga;
                                    movimento.Descrizione = movimentoDto.Descrizione;
                                    if (movimentoDto.IdFornitore != null && movimentoDto.IdFornitore.GetValueOrDefault() > 0)
                                        movimento.FornitoreRiferimento = _daoFactory.GetFornitoreDao().GetById(movimentoDto.IdFornitore.Value, false);

                                    testata.Movimenti.Add(movimento);
                                }
                            }

                            if (movimento != null)
                            {
                                movimentoDto.IdMovimentoRiferimento = movimento.ID;

                                if (movimentoDto.IdSpesa > 0)
                                    movimento.Spesa = _daoFactory.GetSpesaDao().GetById(movimentoDto.IdSpesa, false);

                                if (movimentoDto.IdSottoConto != null)
                                {
                                    if (movimentoDto.IdSottoConto > 0)
                                    {
                                        if (movimento.ContoRiferimento.Codice != _pianoContiService.GetCodiceContoFornitori() && movimento.ContoRiferimento.Codice != _pianoContiService.GetCodiceContoRitenuta() && movimento.ContoRiferimento.Codice != _pianoContiService.GetCodiceContoVersamentiCondomini() && movimento.ContoRiferimento.Codice != _pianoContiService.GetCodiceContoRateCondomini())
                                        {
                                            var sottoConto = _daoFactory.GetSottoContoDao().GetById(movimentoDto.IdSottoConto.Value, false);
                                            movimento.SottoContoRiferimento = sottoConto;
                                        }
                                    }
                                    else
                                    {
                                        try
                                        {
                                            if (movimento.ContoRiferimento != null && !string.IsNullOrEmpty(movimento.ContoRiferimento.Codice))
                                            {
                                                if (movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoBancario())
                                                {
                                                    var banca = _daoFactory.GetDatiBancariCondominiDao().Find(movimentoDto.IdSottoConto.Value * -1, false);
                                                    if (banca != null)
                                                        movimento.ContoCorrenteBancario = banca;
                                                }
                                                else if (movimento.ContoRiferimento.Codice == _pianoContiService.GetCodiceContoVersamentiCondomini())
                                                {
                                                    var soggettoCondominio = _daoFactory.GetSoggettoCondominioDao().Find(movimentoDto.IdSottoConto.Value*-1, false);
                                                    if (soggettoCondominio != null)
                                                        movimento.CondominoRiferimento = soggettoCondominio;
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            _log.ErrorFormat("Errore imprevisto - CONTO CORRENTE - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                return new TestataResult(testata, message);
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato durante l'aggiornamento della quadratura iniziale dei contabili - {0}", ex, Utility.GetMethodDescription());
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentiContatoreCondominiale(Esercizio esercizio, IList<ImportoMovimento> importiAccredito, IList<ImportiDTO> addebitiContatoriDivisionali, DateTime dataRegistrazione, Conto contoAddebito, SottoConto sottoContoAddebito, string descrizione)
        {
            // controllo data registrazione
            var message = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
            if (message.Count > 0)
            {
                var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", dataRegistrazione));
                _log.FatalFormat("Data di registrazione non valida - {0} - data:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), dataRegistrazione, esercizio.ID);
                throw ex;
            }

            var testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null)
            {
                Descrizione = descrizione,
                IsAbilitataArchiviazioneOttica = false,
                IsAllowUpdate = true
            };
            _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

            var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("SC");

            // -------------------------------------------------
            // Calcolo Importo
            // ------------------------------------------------
            var importo = importiAccredito.Sum(item => item.Importo);

            // -------------------------------------------------
            // Segno Movimento
            // ------------------------------------------------
            var segnoContoEconomico = "D";
            if (importo < 0)
            {
                segnoContoEconomico = "A";
                importo = importo * -1;
            }

            // ------------------------------------------------
            // Conto economico da addebitare
            // ------------------------------------------------
            var movimentoContoEconomicoAddebito = new MovimentoContabile(testata, causale, 1, contoAddebito, importo, segnoContoEconomico)
            {
                SottoContoRiferimento = sottoContoAddebito,
                Descrizione = descrizione,
                IsRipartoPersonalizzato = true
            };
            _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoContoEconomicoAddebito);

            // ------------------------------------------------
            // Conto economico da accreditare
            // ------------------------------------------------
            foreach (var item in importiAccredito)
            {
                var movimentoContoEconomicoAccredito = new MovimentoContabile(testata, causale, 2, _daoFactory.GetContoDao().GetById(item.IdConto, false), item.Importo, invertiSegno(segnoContoEconomico)) { Descrizione = descrizione, IsRipartoPersonalizzato = true };
                if(item.IdSottoConto > 0)
                    movimentoContoEconomicoAccredito.SottoContoRiferimento = _daoFactory.GetSottoContoDao().GetById(item.IdSottoConto.GetValueOrDefault(), false);
                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoContoEconomicoAccredito);

                // Ripartizione tra le unità immobiliari
                var totaleMillesimi = addebitiContatoriDivisionali.Sum(mill => mill.Importo);
                foreach (var importiDTO in addebitiContatoriDivisionali)
                {
                    var unita = _daoFactory.GetUnitaImmobiliareDao().GetById(importiDTO.Id, false);
                    var importoUnita = (movimentoContoEconomicoAccredito.GetImportoConSegno() * importiDTO.Importo) / totaleMillesimi;
                    var spesaUnita = new SpeseUnita(importoUnita, unita, null, movimentoContoEconomicoAccredito);
                    _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaUnita);

                }
            }

            return testata;
        }
        public void DeleteTestata(TestataMovimentoContabile testata)
        {
            // --------------------------------------------------------------------
            // Aggiunto codice per rimuovere tutti i riferimenti bugid#4143
            // --------------------------------------------------------------------
            var movimenti = testata.Movimenti.ToList();
            foreach (var movimentoContabile in movimenti)
            {
                movimentoContabile.Testata = null;
                testata.Movimenti.Remove(movimentoContabile);

                if (movimentoContabile.ContoRiferimento != null)
                {
                    movimentoContabile.ContoRiferimento.Movimenti.Remove(movimentoContabile);
                    movimentoContabile.ContoRiferimento = null;
                }

                if (movimentoContabile.FornitoreRiferimento != null)
                {
                    movimentoContabile.FornitoreRiferimento.MovimentiContabili.Remove(movimentoContabile);
                    movimentoContabile.FornitoreRiferimento = null;
                }

                if (movimentoContabile.CondominoRiferimento != null)
                {
                    movimentoContabile.CondominoRiferimento.Movimenti.Remove(movimentoContabile);
                    movimentoContabile.CondominoRiferimento = null;
                }

                if (movimentoContabile.ContoCorrenteBancario != null)
                {
                    movimentoContabile.ContoCorrenteBancario.MovimentiContabili.Remove(movimentoContabile);
                    movimentoContabile.ContoCorrenteBancario = null;
                }

                if (movimentoContabile.EvasioneBancaria != null)
                {
                    movimentoContabile.EvasioneBancaria.MovimentiContabili.Remove(movimentoContabile);
                    movimentoContabile.EvasioneBancaria = null;
                }

            }
            testata.Movimenti.Clear();
            _daoFactory.GetTestataMovimentoContabileDao().Delete(testata);
            // --------------------------------------------------------------------
        }
        public string SetMovimentoAccreditoInteressiMora(Esercizio esercizio, TestataMovimentoContabile testata, Conto conto, string descrizione, decimal importo, DateTime dataRegistrazione)
        {
            try
            {
                var message = string.Empty;

                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("RI");
                if (testata == null)
                    testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null) {IsAllowUpdate = true};

                // controllo data registrazione
                var messageData = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, testata.DataRegistrazione.GetValueOrDefault());
                if (messageData.Count > 0)
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", testata.DataRegistrazione.GetValueOrDefault()));
                    _log.ErrorFormat("Data di registrazione non valida - {0} - data:{1} - conto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), testata.DataRegistrazione.GetValueOrDefault(), conto.ID, esercizio.ID);
                    throw ex;
                }

                var movimento = new MovimentoContabile(testata, causale, testata.Movimenti.Count() + 1, conto, importo, "A") {Descrizione = descrizione};
                _ripartizioneService.ReloadRipartizioneByMovimento(movimento);

                return message;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella creazione del movimento di accredito per interessi di mora - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID);
                throw;
            }
        }
        private decimal getImportoSquadrato(TestataMovimentoContabile testata, bool escludiArrotonadamento = false)
        {
            var importo = 0m;
            foreach (var movimento in testata.Movimenti)
            {
                if(escludiArrotonadamento && movimento.ContoRiferimento.IsArrotondamento)
                    continue;

                if (movimento.Segno == "D")
                    importo -= movimento.Importo.GetValueOrDefault();
                else
                    importo += movimento.Importo.GetValueOrDefault();
            }

            return importo;
        }
        public TestataMovimentoContabile SetMovimentiSollecito(Esercizio esercizio, IList<Sollecito> solleciti, DateTime dataRegistrazione, Conto conto, SottoConto sottoconto)
        {
            try
            {
                // controllo data registrazione
                var message = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
                if (message.Count > 0)
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", dataRegistrazione));
                    _log.FatalFormat("Data di registrazione non valida - {0} - data:{1} - conto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), dataRegistrazione, conto.ID, esercizio.ID);
                    throw ex;
                }

                var testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null)
                {
                    Descrizione = "Addebito solleciti del " + dataRegistrazione.ToShortDateString(),
                    IsAllowUpdate = true
                };

                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IA");
                var numeroRiga = 0;

                // Contropartita
                numeroRiga++;
                var contoContropartita = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, "913");
                new MovimentoContabile(testata, causale, numeroRiga, contoContropartita, solleciti.Sum(item => item.ImportoCompetenza.GetValueOrDefault()), "A");

                foreach (var soll in solleciti)
                {
                    numeroRiga++;
                    var movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, soll.ImportoCompetenza, "D") {SottoContoRiferimento = sottoconto};
                    if (soll.Soggetto != null)
                        movimento.CondominoRiferimento = soll.Soggetto;
                    soll.MovimentoEconomico = movimento;

                    movimento.IsRipartoPersonalizzato = true;

                    var soggetto = soll.Soggetto ?? soll.Persona.SoggettiCondominio.FirstOrDefault(item => item.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.CondominioRiferimento.ID == soll.Esercizio.CondominioRiferimento.ID);
                    if (soggetto != null)
                    {
                        movimento.CondominoRiferimento = soggetto;
                        switch (soggetto.Tipo)
                        {
                            case TipoSoggetto.Proprietario:
                                movimento.PercentualeProprieta = 1;
                                break;
                            case TipoSoggetto.Conduttore:
                                movimento.PercentualeProprieta = 0;
                                break;
                        }
                        new SpeseUnita(soll.ImportoCompetenza, null, soggetto, movimento);
                    }
                }

                _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                return testata;
            }
            catch (Exception ex)
            {
                
                _log.Fatal("Errore inaspettato nella creazione del movimento di addebito competenze per sollecito - " + Utility.GetMethodDescription() + " - IdEsercizio:" + esercizio.ID.ToString(), ex);
                throw;
            }
        }
        public void SetMovimentiPagamenti(Disposizione disposizione, string tipoConto, LogTransazione logTransazione)
        {
            try
            {
                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("PF");
                var lista = new Dictionary<Esercizio, TestataMovimentoContabile>(disposizione.Pagamenti.Count);

                foreach (var pag in disposizione.Pagamenti)
                {
                    try
                    {
                        var numeroRiga = 0;
                        var esercizioRiferimento = getEsercizioCompetenza(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento, pag.Data.GetValueOrDefault());
                        if (esercizioRiferimento == null)
                        {
                            var ex = new InvalidDataException(string.Format("Non trovato nessun esercizio attivo"));
                            _log.FatalFormat("Non trovato nessun esercizio attivo - {0} - condominio:{1} - disposizione:{2} - tipoConto:{3}", ex, Utility.GetMethodDescription(), pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, disposizione.ID, tipoConto);
                            throw ex;
                        }

                        var message = IsAllowDataRegistrazione(new List<int> { esercizioRiferimento.CondominioRiferimento.ID }, esercizioRiferimento, pag.Data.GetValueOrDefault());
                        if (message.Count == 0)
                        {
                            // ================================================
                            // Testata
                            // ================================================
                            TestataMovimentoContabile testata;
                            if (lista.ContainsKey(esercizioRiferimento))
                                testata = lista[esercizioRiferimento];
                            else
                            {
                                testata = new TestataMovimentoContabile(esercizioRiferimento, pag.Data, TipoTestataMovimentoContabileEnum.Automatica, logTransazione);
                                if(logTransazione == null)
                                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                                // Per ora ritengo opportuno avere una testata di movimento contabile distinta per ogni pagamento.
                                // Per avere un testata che accorpi diversi pagamenti è sufficiente scommentare la riga successiva.
                                //lista.Add(esercizioRiferimento, testata);
                            }

                            // ================================================
                            // Debiti VS Fornitori
                            // ------------------------------------------------
                            //  Se è già presente un movimento contabile legato alla ritenute
                            //  vuol dire che il pagamento stato annullato.
                            //  In questo caso il movimento di ritenuta non deve essere generato
                            // ================================================
                            numeroRiga++;
                            var importoFornitori = pag.Importo.GetValueOrDefault();
                            if (pag.RitenutaAcconto != null && pag.RitenutaAcconto.MovimentoContabileCreazione == null)
                                importoFornitori += pag.RitenutaAcconto.Importo.GetValueOrDefault();
                            var movimentoPatrimoniale = new MovimentoContabile(testata, pag.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento, causale, numeroRiga, _daoFactory.GetContoDao().GetByCodice(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.ID, pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoFornitori()), importoFornitori, "D")
                            {
                                Descrizione = string.Format("Pagamento Fatt. n.{0} del {1:d}", pag.ScadenzaRiferimento.SpesaRiferimento.NumeroDocumento, pag.ScadenzaRiferimento.SpesaRiferimento.DataDocumento.GetValueOrDefault())
                            };
                            if(logTransazione == null)
                                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoPatrimoniale);

                            // ================================================
                            // Ritenuta
                            // ================================================
                            decimal importoRitenuta = 0;
                            if (pag.ScadenzaRiferimento.SpesaRiferimento.Detrazione.GetValueOrDefault() == 0 && pag.RitenutaAcconto != null && pag.RitenutaAcconto.MovimentoContabileCreazione == null && pag.RitenutaAcconto.Importo != null && pag.RitenutaAcconto.Importo.GetValueOrDefault() != 0)
                            {
                                numeroRiga++;
                                var segnoRitenuta = "A";
                                importoRitenuta = pag.RitenutaAcconto.Importo.GetValueOrDefault();
                                if (pag.RitenutaAcconto.Importo.GetValueOrDefault() < 0)
                                {
                                    segnoRitenuta = "D";
                                    importoRitenuta = importoRitenuta * -1;
                                }
                                var movimentoRitenuta = new MovimentoContabile(testata, causale, numeroRiga, _daoFactory.GetContoDao().GetByCodice(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.ID, pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoRitenuta()), importoRitenuta, segnoRitenuta)
                                {
                                    FornitoreRiferimento = movimentoPatrimoniale.FornitoreRiferimento
                                };
                                if (!string.IsNullOrEmpty(pag.ScadenzaRiferimento.SpesaRiferimento.NumeroDocumento) && pag.ScadenzaRiferimento.SpesaRiferimento.DataDocumento != null)
                                    movimentoRitenuta.Descrizione = "Ritenuta Fatt. n." + pag.ScadenzaRiferimento.SpesaRiferimento.NumeroDocumento + " del " + pag.ScadenzaRiferimento.SpesaRiferimento.DataDocumento.Value.ToShortDateString();

                                pag.RitenutaAcconto.MovimentoContabileCreazione = movimentoRitenuta;
                                if(logTransazione == null)
                                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoRitenuta);
                            }

                            // ================================================
                            // Conto Patrimoniale
                            // ================================================
                            numeroRiga++;
                            if (pag.Conto == null)
                            {
                                switch (tipoConto)
                                {
                                    case "B":
                                        pag.Conto = _daoFactory.GetContoDao().GetByCodice(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.ID, pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoBancario());
                                        break;
                                    case "C":
                                        pag.Conto = _daoFactory.GetContoDao().GetByCodice(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.ID, pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, "903");
                                        break;
                                }
                            }

                            var segnoPagamento = "A";
                            var importoPagamento = importoFornitori - importoRitenuta;
                            if (importoPagamento < 0)
                            {
                                segnoPagamento = "D";
                                importoPagamento = importoPagamento * -1;

                                // Inverto segno e importo anche per il movimento di Debiti v/Fornitori
                                movimentoPatrimoniale.Segno = invertiSegno("D");
                                movimentoPatrimoniale.Importo = importoFornitori * -1;
                            }

                            var movimentoBancario = new MovimentoContabile(testata, causale, numeroRiga, pag.Conto, importoPagamento, segnoPagamento)
                            {
                                Descrizione = movimentoPatrimoniale.GetDescrizione(),
                                NumeroAssegno = pag.NumeroAssegno,
                                FornitoreRiferimento =
                                    pag.ScadenzaRiferimento.SpesaRiferimento.
                                    FornitoreRiferimento,
                                SottoContoRiferimento = pag.SottoConto,
                                ContoCorrenteBancario = pag.ContoCorrenteBancario
                            };
                            pag.MovimentoContabile = movimentoBancario;
                            if (logTransazione == null)
                                _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoBancario);
                        }
                        else
                        {
                            var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", pag.Data.GetValueOrDefault()));
                            _log.FatalFormat("Data di registrazione non valida - {0} - data:{1} - pagamento:{2} - disposizione:{3} - tipoConto:{4} - esercizio:{5}", ex, Utility.GetMethodDescription(), pag.Data.GetValueOrDefault(), pag.ID, disposizione.ID, tipoConto, esercizioRiferimento.ID);
                            throw ex;
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.FatalFormat("Errore inaspettato durante la scrittura dei movimenti per pagamenti - (SINGOLO PAGAMENTO) - {0} - pagamento:{1} - disposizione:{2}", ex, Utility.GetMethodDescription(), pag.ID, disposizione.ID);
                        throw;
                    }

                }
            }
            catch (Exception ex)
            {
                _log.FatalFormat("Errore inaspettato durante la scrittura dei movimenti per pagamenti - {0} - disposizione:{1}", ex, Utility.GetMethodDescription(), disposizione.ID);
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentiAddebitoCompetenze(Esercizio esercizio, AddebitoCompetenza addebito, DateTime dataRegistrazione, Conto conto, SottoConto sottoConto, string descrizione)
        {
            try
            {
                // controllo data registrazione
                var message = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
                if (message.Count > 0)
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", dataRegistrazione));
                    _log.ErrorFormat("Data di registrazione non valida - {0} - data:{1} - addebito:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), dataRegistrazione, addebito.ID, esercizio.ID);
                    throw ex;
                }

                // se la testata è automatica non è possibile aggiornare gli importi nel dettaglio, se manuale è possibile l'aggiornamento.
                // per ora la testata viene inserita come manuale.
                //TestataMovimentoContabile testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, Sfera.Enums.TipoTestataMovimentoContabileEnum.Automatica);
                var testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Manuale, null) {Descrizione = descrizione, IsAllowUpdate = true};

                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("IA");
                var numeroRiga = 0;

                // Contropartita
                numeroRiga++;
                var contoContropartita = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, "913");
                new MovimentoContabile(testata, causale, numeroRiga, contoContropartita, addebito.Dettaglio.Sum(item => item.Importo), "A") {Descrizione = descrizione};

                foreach (var item in addebito.Dettaglio)
                {
                    try
                    {
                        numeroRiga++;
                        var movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, item.Importo, "D")
                        {
                            SottoContoRiferimento = sottoConto,
                            Descrizione = descrizione,
                            CondominoRiferimento = item.Soggetto
                        };
                        item.MovimentoContabile = movimento;
                    
                        switch (item.Soggetto.Tipo)
                        {
                            case TipoSoggetto.Proprietario:
                                movimento.PercentualeProprieta = 1;
                                break;
                            case TipoSoggetto.Conduttore:
                                movimento.PercentualeProprieta = 0;
                                break;
                        }

                        movimento.IsRipartoPersonalizzato = true;
                        new SpeseUnita(item.Importo, null, item.Soggetto, movimento);

                    }
                    catch (Exception ex)
                    {
                        _log.ErrorFormat("Errore inaspettato nella creazione del movimento di addebito competenze per sollecito - SINGOLO DETTAGLIO - {0} - item:{1}", ex, Utility.GetMethodDescription(), item.ID);
                        throw;
                    }
                }

                addebito.TestataMovimento = testata;
                _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                return testata;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella creazione del movimento di addebito competenze per sollecito - {0} - esercizio:{1} - dataRegistrazione:{2} - addebito:{3} - conto:{4} - sottoconto:{5} - descrizione:{6}", ex, Utility.GetMethodDescription(), esercizio != null ? esercizio.ID.ToString() : "<NULL>", dataRegistrazione, addebito != null ? addebito.ID.ToString() : "<NULL>", conto != null ? conto.ID.ToString() : "<NULL>", sottoConto != null ? sottoConto.ID.ToString() : "<NULL>", descrizione);
                throw;
            }
        }
        public MovimentoContabile SetMovimentiStornoPagamento(Pagamento pag, decimal importo, DateTime dataRegistrazione)
        {
            try
            {
                var esercizio = _daoFactory.GetEsercizioDao().GetEsercizioCompetenza(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento, dataRegistrazione);
                var message = IsAllowDataRegistrazione(new List<int> { pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
                if (message.Count == 0)
                {
                    var numeroRiga = 0;
                    var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("SS");

                    // ================================================
                    // Testata
                    // ================================================
                    var testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Automatica, null);
                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                    // ================================================
                    // Debiti VS Fornitori
                    // ================================================
                    numeroRiga++;

                    var segno = "A";
                    if (importo < 0)
                    {
                        segno = "D";
                        importo = importo * -1;
                    }

                    var movimentoPatrimoniale = new MovimentoContabile(testata, pag.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento, causale, numeroRiga,
                                                                       _daoFactory.GetContoDao().GetByCodice(pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.ID, 
                                                                       pag.ScadenzaRiferimento.SpesaRiferimento.EsercizioRiferimento.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoFornitori()), importo, segno)
                    {
                        Descrizione = "Storno Fatt. n." + pag.ScadenzaRiferimento.SpesaRiferimento.NumeroDocumento + " del " + pag.ScadenzaRiferimento.SpesaRiferimento.DataDocumento.GetValueOrDefault().ToShortDateString()
                    };
                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoPatrimoniale);

                    // ================================================
                    // Conto Patrimoniale
                    // ================================================
                    numeroRiga++;

                    var movimentoBancario = new MovimentoContabile(testata, causale, numeroRiga, pag.Conto, importo, invertiSegno(segno))
                    {
                        Descrizione = movimentoPatrimoniale.Descrizione,
                        FornitoreRiferimento = pag.ScadenzaRiferimento.SpesaRiferimento.FornitoreRiferimento,
                        SottoContoRiferimento = pag.SottoConto,
                        ContoCorrenteBancario = pag.ContoCorrenteBancario
                    };

                    pag.MovimentoContabileStorno = movimentoBancario;

                    _daoFactory.GetMovimentoContabileDao().SaveOrUpdate(movimentoBancario);

                    return movimentoBancario;
                }

                var ex = new InvalidDataException(string.Format("La data di registrazione {0:d} non è valida", dataRegistrazione));

                _log.ErrorFormat("Data di registrazione non valida - {0} - data:{1} - pagamento:{2} - importo:{3}", ex, Utility.GetMethodDescription(), dataRegistrazione, pag.ID, importo);
                throw ex;

            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nella funzione - {0} - data:{1} - pagamento:{2} - importo:{3}", ex, Utility.GetMethodDescription(), dataRegistrazione, pag.ID, importo);
                throw;
            }
        }
        public TestataMovimentoContabile SetMovimentiAddebitoCompetenze(AddebitoCompetenzaDTO addebito)
        {
            try
            {
                // se la testata è automatica non è possibile aggiornare gli importi nel dettaglio, se manuale è possibile l'aggiornamento.
                // per ora la testata viene inserita come manuale.
                TestataMovimentoContabile testata;
                var esercizio = _daoFactory.GetEsercizioDao().Find(addebito.IdEsercizio, false);
                var dataRegistrazione = addebito.DataRegistrazioneMovimentoContabile;

                // controllo data registrazione
                var messageData = IsAllowDataRegistrazione(new List<int> { esercizio.CondominioRiferimento.ID }, esercizio, dataRegistrazione);
                if (messageData.Count == 0)
                {
                    testata = new TestataMovimentoContabile(esercizio, dataRegistrazione, TipoTestataMovimentoContabileEnum.Manuale, null) {Descrizione = addebito.Descrizione, IsAllowUpdate = true};

                    var causale = _daoFactory.GetCausaleContabileDao().Find(addebito.IdCausale, false) ?? _daoFactory.GetCausaleContabileDao().GetByCodice("IA");
                    var numeroRiga = 0;

                    // Contropartita
                    numeroRiga++;
                    var contoContropartita = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, "913");
                    new MovimentoContabile(testata, causale, numeroRiga, contoContropartita, addebito.Dettaglio.Sum(item => item.Importo), "A") {Descrizione = addebito.Descrizione};

                    foreach (var item in addebito.Dettaglio)
                    {
                        try
                        {
                            if (item.Importo != 0)
                            {
                                numeroRiga++;

                                var conto = _daoFactory.GetContoDao().Find(item.IdConto, false);
                                if (conto != null)
                                {
                                    SottoConto sottoConto = null;
                                    if (item.IdSottoConto != null)
                                        sottoConto = _daoFactory.GetSottoContoDao().GetById(item.IdSottoConto.Value, false);
                                    var soggetto = _daoFactory.GetSoggettoCondominioDao().Find(item.IdCondomino.GetValueOrDefault(), false);
                                    if (soggetto != null)
                                    {
                                        var movimento = new MovimentoContabile(testata, causale, numeroRiga, conto, item.Importo, "D")
                                        {
                                            SottoContoRiferimento = sottoConto,
                                            Descrizione = item.DescrizioneMovimentoContabile,
                                            CondominoRiferimento = soggetto
                                        };

                                        switch (soggetto.Tipo)
                                        {
                                            case TipoSoggetto.Proprietario:
                                                movimento.PercentualeProprieta = 1;
                                                break;
                                            case TipoSoggetto.Conduttore:
                                                movimento.PercentualeProprieta = 0;
                                                break;
                                        }

                                        movimento.IsRipartoPersonalizzato = true;
                                        new SpeseUnita(item.Importo, null, soggetto, movimento);

                                        var dettaglio = _daoFactory.GetDettaglioAddebitoCompetenzaDao().Find(item.ID, false);
                                        if (dettaglio != null)
                                        {
                                            dettaglio.MovimentoContabile = movimento;
                                            dettaglio.Soggetto = soggetto;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            
                            _log.Fatal(
                                "Errore inaspettato nella creazione del movimento di addebito competenze per sollecito - SINGOLO SOGGETTO - " +
                                Utility.GetMethodDescription() + " - id:" + item.ID + " - importo:" +
                                item.Importo + " - soggetto:" + item.IdCondomino + " - conto:" + item.IdConto +
                                " - sottoconto:" + item.IdSottoConto.GetValueOrDefault() + " - addebito:" + addebito.ID +
                                " - IdEsercizio:" + addebito.IdEsercizio, ex);
                            throw;
                        }

                    }

                    var addebitoItem = _daoFactory.GetAddebitoCompetenzaDao().Find(addebito.ID, false);
                    if (addebitoItem != null)
                        addebitoItem.TestataMovimento = testata;

                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);
                }
                else
                {
                    var ex = new InvalidDataException(string.Format("La data di registrazione {0} non è valida", dataRegistrazione));
                    
                    _log.Fatal("Data di registrazione non valida - " + Utility.GetMethodDescription() + " - data:" + dataRegistrazione + " - addebito:" + addebito.ID + " - IdEsercizio:" + addebito.IdEsercizio, ex);
                    throw ex;
                }

                return testata;
            }
            catch (Exception ex)
            {
                
                _log.Fatal("Errore inaspettato nella creazione del movimento di addebito competenze per sollecito - " + Utility.GetMethodDescription() + " - addebito:" + addebito.ID + " - IdEsercizio:" + addebito.IdEsercizio, ex);
                throw;
            }
        }
Exemple #29
0
        private void deleteTestata(TestataMovimentoContabile testata, IDaoFactory daoFactory)
        {
            testata.SpesaRiferimento = null;
            testata.EsercizioRiferimento = null;

            // --------------------------------------------------------------------
            // Aggiunto codice per rimuovere tutti i riferimenti bugid#4143
            // --------------------------------------------------------------------
            var movimenti = testata.Movimenti.ToList();
            foreach (var movimentoContabile in movimenti)
            {
                movimentoContabile.Testata = null;
                testata.Movimenti.Remove(movimentoContabile);

                if (movimentoContabile.ContoRiferimento != null)
                {
                    movimentoContabile.ContoRiferimento.Movimenti.Remove(movimentoContabile);
                    movimentoContabile.ContoRiferimento = null;
                }

                if (movimentoContabile.FornitoreRiferimento != null)
                {
                    movimentoContabile.FornitoreRiferimento.MovimentiContabili.Remove(movimentoContabile);
                    movimentoContabile.FornitoreRiferimento = null;
                }
            }
            testata.Movimenti.Clear();
            daoFactory.GetTestataMovimentoContabileDao().Delete(testata);
            // --------------------------------------------------------------------

        }
        public string ChiusuraContiEconomici(Esercizio esercizio, IEnumerable<ReportRipartizioneBilancioDTO> ripartizione)
        {
            try
            {
                var message = string.Empty;

                var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("C1");
                var contoCondomini = _daoFactory.GetContoDao().GetByCodice(esercizio.ID, esercizio.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoVersamentiCondomini());

                // =======================================================================================
                //  Tutti i conti economici sono chiusi nel conto Crediti v/condomini
                // =======================================================================================
                var testataEconomico = new TestataMovimentoContabile(esercizio, esercizio.DataChiusura, TipoTestataMovimentoContabileEnum.Automatica, null) { AperturaChiusuraConti = true };
                var conti = esercizio.CondominioRiferimento.Conti.Where(item => item.Tipo == TipoContoEconomicoEnum.Economico && item.PresenteBilancio).ToList();
                var contiChiusuraStraordinario = getContiEconomiciChiusuraStraordinario(esercizio.CondominioRiferimento.ID);
                foreach (var conto in conti)
                {
                    try
                    {
                        var importoConto = Math.Round(GetSaldoConto(esercizio.ID, conto.ID, contiChiusuraStraordinario), 2);
                        var importoRipartizione = 0m;

                        var reportRipartizioneBilancioDtos = ripartizione as IList<ReportRipartizioneBilancioDTO> ?? ripartizione.ToList();
                        var conto1 = conto;
                        var spesePerCondomino = reportRipartizioneBilancioDtos.Where(item => item.IdConto == conto1.ID && item.IdPartecipante > 0).GroupBy(item => item.IdPartecipante);
                        var indexEconomico = 0;
                        foreach (var reportRipartizioneBilancioDTO in spesePerCondomino)
                        {
                            try
                            {
                                var soggetto = _daoFactory.GetSoggettoCondominioDao().GetById(reportRipartizioneBilancioDTO.Key, false);
                                var importo = Math.Round(reportRipartizioneBilancioDTO.Sum(item => item.Importo.GetValueOrDefault()), 2);
                                importoRipartizione += importo;
                                if (importo != 0)
                                {
                                    var segno = "A";
                                    if (importo < 0)
                                    {
                                        segno = "D";
                                        importo = importo * -1;
                                    }

                                    // ---------------------------------------------------------------------
                                    //  Chiusura conto economico
                                    // ---------------------------------------------------------------------
                                    indexEconomico++;
                                    var descrizione = string.Format("Chiusura conto '{0} {1}' - {2} Esercizio '{3}'", conto.Codice, conto.Descrizione, soggetto.DisplayName, esercizio.DisplayName);
                                    new MovimentoContabile(testataEconomico, causale, 1, conto, importo, segno)
                                    {
                                        Descrizione = descrizione,
                                        CondominoRiferimento = soggetto,
                                        Stato = StatoMovimentoContabileEnum.Evaso
                                    };
                                }

                            }
                            catch (Exception ex)
                            {
                                _log.FatalFormat("Errore inaspettato durante la chiusura dei conti economici (SINGOLO SOGGETTO) - {0} - conto:{1} - soggetto:{1}", ex, Utility.GetMethodDescription(), conto.ID, reportRipartizioneBilancioDTO.Key);
                                throw;
                            }
                        }
                        
                        // ---------------------------------------------------------------------
                        // Contropartita crediti v/condomini
                        // ---------------------------------------------------------------------
                        var segnoConto = "D";
                        var importoRipartoConto = importoRipartizione;
                        if (importoRipartoConto < 0)
                        {
                            segnoConto = "A";
                            importoRipartoConto = importoRipartoConto * -1;
                        }

                        indexEconomico++;
                        new MovimentoContabile(testataEconomico, causale, indexEconomico, contoCondomini, importoRipartoConto, segnoConto)
                        {
                            Descrizione = string.Format("Chiusura conto '{0} {1}' - Esercizio '{2}'", conto.Codice, conto.Descrizione, esercizio.DisplayName),
                            Stato = StatoMovimentoContabileEnum.Evaso,
                        };

                        // ---------------------------------------------------------------------
                        // L'importo del conto non corrisponde con l'importo della ripartizione (dovuto all'arrotondamento tipico del riparto spese)
                        // ---------------------------------------------------------------------
                        if (importoConto != importoRipartizione)
                        {
                            var importoArrotondamento = importoConto - importoRipartizione;
                            var segno = "A";
                            if (importoArrotondamento < 0)
                            {
                                segno = "D";
                                importoArrotondamento = importoArrotondamento * -1;
                            }

                            //  Conto economico
                            // ---------------------------------------------------------------------
                            indexEconomico++;
                            var descrizione = string.Format("Arrotondamento per riparto conto '{0} {1}' - Esercizio '{2}'", conto.Codice, conto.Descrizione, esercizio.DisplayName);
                            new MovimentoContabile(testataEconomico, causale, 1, conto, importoArrotondamento, segno)
                            {
                                Descrizione = descrizione,
                                Stato = StatoMovimentoContabileEnum.Evaso
                            };

                            // Contropartita conto Arrotondamenti
                            // ---------------------------------------------------------------------
                            indexEconomico++;
                            var contoArrotondamenti = _pianoContiService.GetContoArrotondamenti(esercizio);
                            _daoFactory.GetContoDao().SaveOrUpdate(contoArrotondamenti);
                            new MovimentoContabile(testataEconomico, causale, indexEconomico, contoArrotondamenti, importoArrotondamento, invertiSegno(segno))
                            {
                                Descrizione = descrizione,
                                Stato = StatoMovimentoContabileEnum.Evaso,
                            };
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.FatalFormat("Errore inaspettato durante la chiusura dei conti economici (SINGOLO CONTO) - {0} - conto:{1}", ex, Utility.GetMethodDescription(), conto.ID);
                        throw;
                    }
                }

                if (testataEconomico.Movimenti.Count > 0)
                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testataEconomico);

                return message;
            }
            catch (Exception ex)
            {
                _log.FatalFormat("Errore inaspettato durante la chiusura dei conti economici - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID);
                throw;
            }
        }