public SpeseUnitaDTO GetByDomainEntity(SpeseUnita spesa)
 {
     try
     {
         return setSpeseUnitaDto(spesa);
     }
     catch (Exception ex)
     {
         
         _log.Error("Errore nel caricamento delle spese per unità immobiliare - " + Library.Utility.GetMethodDescription() + " - id:" + spesa.ID, ex);
         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 TestataMovimentoContabile TrasferimentoSaldiStraordinarioInOrdinario(int idEsercizioStraordinario, int idEsercizioOrdinario, string nomeContoOrdinario, int ordineConto, IBilancioService bilancioService, DateTime? dataChiusura, bool chiusuraTemporanea)
        {
            try
            {
                var esercizioStraordinario = _daoFactory.GetEsercizioDao().GetById(idEsercizioStraordinario, false);
                var esercizioOrdinario = _daoFactory.GetEsercizioDao().GetById(idEsercizioOrdinario, false);
                if (!chiusuraTemporanea)
                {
                    var messagesDataRegistrazione = _movimentiContabiliService.IsAllowDataRegistrazione(new List<int> {esercizioStraordinario.CondominioRiferimento.ID}, esercizioOrdinario, dataChiusura.GetValueOrDefault());
                    if (messagesDataRegistrazione.Count > 0)
                    {
                        var messageDataRegistrazione = messagesDataRegistrazione.Aggregate(string.Empty, (current, mess) => current + (mess + Environment.NewLine));
                        var ex = new InvalidDataException($"La data di registrazione {dataChiusura.GetValueOrDefault()} non è valida" + Environment.NewLine + messageDataRegistrazione);
                        _log.Fatal(ex.Message, ex);
                        throw ex;
                    }

                    var contoOrdinario = new Conto(esercizioOrdinario.CondominioRiferimento, TipoContoEconomicoEnum.Economico, TipoPeriodoCompetenzaContabile.Esercizio, nomeContoOrdinario, false, false, false)
                    {
                        PresenteBilancio = true,
                        CustomField = false,
                        EsercizioRiferimento = esercizioOrdinario,
                        Ordine = ordineConto,
                        Codice = ordineConto.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0'),
                        PercentualeProprieta = 1,
                        IsSpesePersonali = true,
                        TrasferimentoSaldiStraordinario = true
                    };

                    var contoArrotondamenti = _pianoContiService.GetContoArrotondamenti(esercizioOrdinario);
                    _daoFactory.GetContoDao().SaveOrUpdate(contoArrotondamenti);

                    var sottocontoOrdinario = new SottoConto(contoOrdinario, nomeContoOrdinario);

                    esercizioStraordinario.ContoEconomicoOrdinarioChiusuraStraordinario = contoOrdinario;

                    var items = bilancioService.GetDataSourceRipartizioneBilancioConsuntivo(esercizioStraordinario.ID, null, null, null, null, null, null, false, false, TipoAccorpamentoRateEnum.Nessuno, false, false, false, false, null).ToList();
                    var ripartoEconomici = items.Where(item => item.OrdineConto < 9900).ToList();

                    var testata = new TestataMovimentoContabile(esercizioOrdinario, dataChiusura, TipoTestataMovimentoContabileEnum.Automatica, null);
                    _daoFactory.GetTestataMovimentoContabileDao().SaveOrUpdate(testata);

                    esercizioStraordinario.TestataContabileChiusura = testata;
                    var causale = _daoFactory.GetCausaleContabileDao().GetByCodice("ST");

                    // ===========================================================================
                    // Movimenti Chiusura/Apertura conti economici
                    // ---------------------------------------------------------------------------
                    // Chiusura di tutti i conti economici della gestione starordianaria (in avere), 
                    // aprendo un conto economico "<CONTO ECONOMICO SALDI STRAORDINARIA>" nella gestione ordinaria (in dare), per il totale della spesa. 
                    // La spesa deve essere ripartita sulla base dei conti utilizzati nella gestione straordinaria.  
                    // I conti devono essere addebitati per soggetto.
                    // ===========================================================================
                    var numeroRiga = 0;
                    foreach (var itemRiparto in ripartoEconomici)
                    {
                        // Gli arrotondamenti hanno IdPartecipante == 0, queste righe devono essere usate per registrare i movimenti di arrotondamento.
                        if (itemRiparto.IdPartecipante > 0)
                        {
                            var importo = itemRiparto.Importo.GetValueOrDefault();
                            if (importo != 0)
                            {
                                try
                                {
                                    var soggetto = _daoFactory.GetSoggettoCondominioDao().GetById(itemRiparto.IdPartecipante, false);

                                    // ---------------------------------------------
                                    // Apertura conto economico nell'ordinario
                                    // ---------------------------------------------
                                    numeroRiga++;
                                    var movimentoAperturaOrdinario = new MovimentoContabile(testata, causale, 1, contoOrdinario, numeroRiga, "D")
                                    {
                                        Descrizione = $"Saldo Gestione Straordinaria '{esercizioStraordinario.Descrizione}' - {soggetto.DisplayName}",
                                        CondominoRiferimento = soggetto,
                                        SottoContoRiferimento = sottocontoOrdinario
                                    };

                                    // Calcolo del segno
                                    var segnoEconomico = "D";
                                    if (importo < 0)
                                    {
                                        segnoEconomico = "A";
                                        importo = importo * -1;
                                    }
                                    movimentoAperturaOrdinario.Segno = segnoEconomico;
                                    movimentoAperturaOrdinario.Importo = importo;

                                    // ---------------------------------------------
                                    // Chiusura conto economico nello straordinario
                                    // ---------------------------------------------
                                    numeroRiga++;
                                    var movimentoChiusuraStraordinario = new MovimentoContabile(testata, causale, numeroRiga, _daoFactory.GetContoDao().GetById(itemRiparto.IdConto, false), importo, invertiSegno(segnoEconomico)) { Descrizione = string.Format("Chiusura conto {0}: '{1}' - {2}", itemRiparto.DescrizioneConto, esercizioStraordinario.Descrizione, soggetto.DisplayName), CondominoRiferimento = movimentoAperturaOrdinario.CondominoRiferimento };

                                    // ---------------------------------------------
                                    // Dettaglio spesa unità
                                    // ---------------------------------------------
                                    var spesaUnita = new SpeseUnita(itemRiparto.Importo, null, soggetto, movimentoAperturaOrdinario);
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore inaspettato durante il trasferimento saldi dell'esercizio straordinario all'ordinario - MOVIMENTO CONTO ECONOMICO - {0} - importo:{1} - idEsercizioStraordinario:{2} - idEsercizioOrdinario:{3} - nomeContoOrdinario:{4} - ordineConto:{5}", ex, Library.Utility.GetMethodDescription(), importo, idEsercizioStraordinario, idEsercizioOrdinario, nomeContoOrdinario, ordineConto);
                                    throw;
                                }
                            }
                        }
                        else
                        {
                            // ---------------------------------------------
                            // Apertura conto economico nell'ordinario
                            // ---------------------------------------------
                            var importo = itemRiparto.Importo;
                            numeroRiga++;
                            var movimentoAperturaOrdinario = new MovimentoContabile(testata, causale, 1, contoArrotondamenti, numeroRiga, "D") { Descrizione = $"Saldo Gestione Straordinaria '{esercizioStraordinario.Descrizione}'" };

                            // Calcolo del segno
                            var segnoEconomico = "D";
                            if (importo < 0)
                            {
                                segnoEconomico = "A";
                                importo = importo * -1;
                            }
                            movimentoAperturaOrdinario.Segno = segnoEconomico;
                            movimentoAperturaOrdinario.Importo = importo;

                            // ---------------------------------------------
                            // Chiusura conto economico nello straordinario
                            // ---------------------------------------------
                            numeroRiga++;
                            var movimentoChiusuraStraordinario = new MovimentoContabile(testata, causale, numeroRiga, _daoFactory.GetContoDao().GetById(itemRiparto.IdConto, false), importo, invertiSegno(segnoEconomico)) { Descrizione = $"Arrondamento chiusura conto {itemRiparto.DescrizioneConto}: '{esercizioStraordinario.Descrizione}'"
                            };
                        }
                    }

                    // ===========================================================================
                    // Movimenti Chiusura/Apertura crediti v/condomini gestione straordinaria
                    // ---------------------------------------------------------------------------
                    // Chiusura del conto Crediti v/condomini della "<GESTIONE STRAORDINARIA>" 
                    // per i versamenti effettuati nella gestione straordinaria, sul conto "<CONTO ECONOMICO SALDI STRAORDINARIA>", 
                    // accreditando i singoli soggetti.
                    // ===========================================================================
                    var ripartoVersamenti = items.Where(item => item.OrdineConto == 9992).ToList();

                    // Aggiungo soggetti con saldo inziale ma senza versamenti
                    var saldiIniziali = items.Where(item => item.OrdineConto == 9991).ToList();
                    var ripartoSaldiIniziali = new List<ReportRipartizioneBilancioDTO>(saldiIniziali.Count);
                    foreach (var reportRipartizioneBilancioDTO in saldiIniziali)
                    {
                        if (ripartoVersamenti.All(item => item.IdPartecipante != reportRipartizioneBilancioDTO.IdPartecipante))
                        {
                            reportRipartizioneBilancioDTO.Importo = reportRipartizioneBilancioDTO.Importo.GetValueOrDefault()*-1;
                            ripartoVersamenti.Add(reportRipartizioneBilancioDTO);
                        }
                        else
                            ripartoSaldiIniziali.Add(reportRipartizioneBilancioDTO);
                    }

                    var contoVersamentiEsercizioStraordinario = _daoFactory.GetContoDao().GetByCodice(esercizioStraordinario.ID, esercizioStraordinario.CondominioRiferimento.ID, _pianoContiService.GetCodiceContoVersamentiCondomini());

                    foreach (var itemRiparto in ripartoVersamenti)
                    {
                        var importo = itemRiparto.Importo.GetValueOrDefault();

                        // aggiungo eventuale saldo iniziale
                        var itemSaldoIniziale = ripartoSaldiIniziali.FirstOrDefault(item => item.IdPartecipante == itemRiparto.IdPartecipante);
                        var importoSaldoIniziale = 0m;
                        if (itemSaldoIniziale != null)
                            importoSaldoIniziale = itemSaldoIniziale.Importo.GetValueOrDefault();
                        importo -= importoSaldoIniziale;

                        try
                        {
                            // Gli arrotondamenti hanno IdPartecipante == 0, escludo queste righe.
                            if (itemRiparto.IdPartecipante > 0)
                            {
                                var soggetto = _daoFactory.GetSoggettoCondominioDao().GetById(itemRiparto.IdPartecipante, false);

                                // ---------------------------------------------
                                // Apetura conto economico nell'ordinario
                                // ---------------------------------------------
                                numeroRiga++;
                                var movimentoAperturaOrdinario = new MovimentoContabile(testata, causale, numeroRiga, contoOrdinario, 0, "D")
                                {
                                    Descrizione = $"Saldo Gestione Straordinaria '{esercizioStraordinario.Descrizione}' - {soggetto.DisplayName}",
                                    CondominoRiferimento = soggetto,
                                    SottoContoRiferimento = sottocontoOrdinario
                                };

                                // Calcolo del segno
                                var segnoEconomico = "A";
                                if (importo < 0)
                                {
                                    segnoEconomico = "D";
                                    importo = importo * -1;
                                }
                                movimentoAperturaOrdinario.Segno = segnoEconomico;
                                movimentoAperturaOrdinario.Importo = importo;

                                // ---------------------------------------------
                                // Chiusura conto crediti v/condomini nello straordinario
                                // ---------------------------------------------
                                numeroRiga++;
                                var movimentoChiusuraStraordinario = new MovimentoContabile(testata, causale, numeroRiga, contoVersamentiEsercizioStraordinario, importo, invertiSegno(segnoEconomico)) { Descrizione = string.Format("Chiusura conto {0}: '{1}' - {2}", contoVersamentiEsercizioStraordinario.Descrizione, esercizioStraordinario.Descrizione, soggetto.DisplayName), CondominoRiferimento = movimentoAperturaOrdinario.CondominoRiferimento };

                                // ---------------------------------------------
                                // Dettaglio spesa unità
                                // ---------------------------------------------
                                var spesaUnita = new SpeseUnita((itemRiparto.Importo.GetValueOrDefault() - importoSaldoIniziale) * -1, null, soggetto, movimentoAperturaOrdinario);
                            }
                        }
                        catch (Exception ex)
                        {
                            _log.FatalFormat("Errore inaspettato durante il trasferimento saldi dell'esercizio straordinario all'ordinario - MOVIMENTO VERSAMENTI - {0} - importo:{1} - idEsercizioStraordinario:{2} - idEsercizioOrdinario:{3} - nomeContoOrdinario:{4} - ordineConto:{5}", ex, Library.Utility.GetMethodDescription(), importo, idEsercizioStraordinario, idEsercizioOrdinario, nomeContoOrdinario, ordineConto);
                            throw;
                        }
                    }

                    return testata;
                }
                else
                {
                    // ====================================================================
                    //  Chiusura temporanea dei conti
                    // ====================================================================
                    var movimentiEconomici = _daoFactory.GetMovimentoContabileDao().GetByEsercizioEconomici(esercizioStraordinario, esercizioOrdinario.DataApertura, esercizioOrdinario.DataChiusura);
                    var contoPatrimoniale = _pianoContiService.GetContoChiusuraStraordinario(esercizioStraordinario);
                    var testataChiusura = new TestataMovimentoContabile(esercizioStraordinario, dataChiusura, TipoTestataMovimentoContabileEnum.Automatica, null)
                    {
                        EsercizioOrdinarioChiusura = esercizioOrdinario,
                        Descrizione = $"Chiusura esercizio straordinario: '{esercizioStraordinario.DisplayName}' per chiusura dell'ordinario: '{esercizioOrdinario.DisplayName}'"
                    };

                    var causaleChiusura = _daoFactory.GetCausaleContabileDao().GetByCodice("C2");
                    var index = 0;

                    // =================================================
                    // Calcolo tutti i saldi dei conti
                    // =================================================
                    var saldiContoSottoconto = new Dictionary<string, MovimentoContabile>();
                    foreach (var movimentoContabile in movimentiEconomici)
                    {
                        var key = _movimentiContabiliService.GetKeyContoSottoconto(movimentoContabile);
                        if (saldiContoSottoconto.ContainsKey(key))
                        {
                            var movimentoChiusura = saldiContoSottoconto[key];
                            movimentoChiusura.Importo += movimentoContabile.GetImportoConSegno();
                        }
                        else
                        {
                            index++;
                            var movimentoChiusura = new MovimentoContabile(testataChiusura, causaleChiusura, index, movimentoContabile.ContoRiferimento, movimentoContabile.GetImportoConSegno(), string.Empty)
                            {
                                Descrizione = $"Chiusura esercizio straordinario: '{esercizioStraordinario.DisplayName}' per chiusura dell'ordinario: '{esercizioOrdinario.DisplayName}'",
                                CondominoRiferimento = movimentoContabile.CondominoRiferimento,
                                FornitoreRiferimento = movimentoContabile.FornitoreRiferimento,
                                ContoCorrenteBancario = movimentoContabile.ContoCorrenteBancario
                            };

                            saldiContoSottoconto.Add(key, movimentoChiusura);
                        }
                    }

                    // =================================================
                    // Elaboro i segni e creo le contropartite
                    // =================================================
                    foreach (var kvp in saldiContoSottoconto)
                    {
                        var movimentoContabile = kvp.Value;
                        if (movimentoContabile.ContoRiferimento.Tipo == TipoContoEconomicoEnum.Economico)
                        {
                            movimentoContabile.Segno = "A";
                            if (movimentoContabile.Importo < 0)
                            {
                                movimentoContabile.Segno = "D";
                                movimentoContabile.Importo = movimentoContabile.Importo*-1;
                            }
                        }
                        else if (movimentoContabile.ContoRiferimento.Tipo == TipoContoEconomicoEnum.Patrimoniale)
                        {
                            movimentoContabile.Segno = "D";
                            if (movimentoContabile.Importo < 0)
                            {
                                movimentoContabile.Segno = "A";
                                movimentoContabile.Importo = movimentoContabile.Importo * -1;
                            }
                        }

                        var movimentoPatrimoniale = new MovimentoContabile(testataChiusura, causaleChiusura, index, contoPatrimoniale, movimentoContabile.Importo, invertiSegno(movimentoContabile.Segno))
                        {
                            Descrizione = $"Chiusura conto '{kvp.Value.ContoRiferimento.Descrizione}' esercizio straordinario: '{esercizioStraordinario.DisplayName}' per chiusura dell'ordinario: '{esercizioOrdinario.DisplayName}'"
                        };
                    }

                    return testataChiusura;
                }
            }
            catch (Exception ex)
            {
                _log.FatalFormat("Errore inaspettato durante il trasferimento saldi dell'esercizio straordinario all'ordinario - {0} - idEsercizioStraordinario:{1} - idEsercizioOrdinario:{2} - nomeContoOrdinario:{3} - ordineConto:{4} - dataChiusura:{5:d}", ex, Library.Utility.GetMethodDescription(), idEsercizioStraordinario, idEsercizioOrdinario, nomeContoOrdinario, ordineConto, dataChiusura.GetValueOrDefault());
                throw;
            }
        }
        private bool update(SpeseUnitaDTO spesaDto, out SpeseUnita spesa)
        {
            var result = false;
            spesa = null;
            var daoFactory = _windsorRepository.GetDaoFactory(_info.Azienda);

            try
            {
                spesa = daoFactory.GetSpeseUnitaDao().GetById(spesaDto.ID, false);

                // Condizione necessaria per il controllo del fatto che sul DB ho una versione uguale o più vecchia
                if (spesaDto.Version == spesa.Version)
                {
                    spesa.Importo = spesaDto.Importo;
                    spesa.MovimentoRiferimento = daoFactory.GetMovimentoContabileDao().GetById(spesaDto.IdMovimentoRiferimento, false);
                    
                    if(spesaDto.IdUnitaRiferimento != null)
                        spesa.UnitaRiferimento = daoFactory.GetUnitaImmobiliareDao().GetById(spesaDto.IdUnitaRiferimento.GetValueOrDefault(), false);

                    if (spesaDto.IdSoggetto != null)
                        spesa.SoggettoCondominio = daoFactory.GetSoggettoCondominioDao().GetById(spesaDto.IdSoggetto.GetValueOrDefault(), false);

                    result = true;
                }
                else
                {
                    // Eccezione: Sul db c'è qualche cosa di più nuovo.
                    _log.Error("Errore nel salvataggio della gestione dei riparti delle unità id:" + spesaDto.ID.ToString() + " - il dato sul db è più recente di quello che si vuole salvare");
                }
            }
            catch (Exception ex)
            {
                
                _log.Error("Errore nel salvataggio della gestione dei riparti delle unità - " + Library.Utility.GetMethodDescription() + " - id:" + spesaDto.ID.ToString(), ex);
                throw;
            }

            return result;
        }
        private bool insert(SpeseUnitaDTO spesaDto, out SpeseUnita spesa)
        {
            bool result;
            spesa = null;

            try
            {
                if (_movimento != null)
                {
                    var daoFactory = _windsorRepository.GetDaoFactory(_info.Azienda);

                    UnitaImmobiliare unitaImmobiliare = null;
                    if (spesaDto.IdUnitaRiferimento != null)
                        unitaImmobiliare = daoFactory.GetUnitaImmobiliareDao().Find(spesaDto.IdUnitaRiferimento.GetValueOrDefault(), false);

                    SoggettoCondominio soggettoCondominio = null;
                    if (spesaDto.IdSoggetto != null)
                        soggettoCondominio = daoFactory.GetSoggettoCondominioDao().Find(spesaDto.IdSoggetto.GetValueOrDefault(), false);

                    spesa = new SpeseUnita(spesaDto.Importo, unitaImmobiliare, soggettoCondominio, _movimento);
                    daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesa);
                }
                result = true;
            }
            catch (Exception ex)
            {
                
                _log.Error("Errore nell'inserimento del riparto delle unità - " + Library.Utility.GetMethodDescription(), ex);
                result = false;
            }

            return result;
        }
Exemple #6
0
        private bool isAddebitatoScalaStabile(SpeseUnita spesaUnita, int? idStabile, int? idScala)
        {
            if (idStabile != null || idScala != null)
            {
                var unita = spesaUnita.UnitaRiferimento;
                if (unita == null && spesaUnita.SoggettoCondominio != null)
                    unita = spesaUnita.SoggettoCondominio.UnitaImmobiliare;

                if (unita != null)
                {
                    if (idStabile != null)
                        return unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID == idStabile.Value;
                    else
                        return unita.GruppoStabileRiferimento.ID == idScala.Value;
                }
            }

            return true;
        }
        private SpeseUnitaDTO setSpeseUnitaDto(SpeseUnita spesa)
        {
            try
            {
                var dto = new SpeseUnitaDTO
                {
                    ID = spesa.ID,
                    Importo = spesa.Importo,
                    IdMovimentoRiferimento = spesa.MovimentoRiferimento.ID,
                };

                if (spesa.UnitaRiferimento != null)
                {
                    dto.IdUnitaRiferimento = spesa.UnitaRiferimento.ID;
                    dto.DescrizioneUnitaRiferimento = spesa.UnitaRiferimento.Descrizione;

                }

                if (spesa.SoggettoCondominio != null)
                {
                    dto.IdSoggetto = spesa.SoggettoCondominio.ID;
                    dto.DescrizioneUnitaRiferimento = spesa.SoggettoCondominio.DisplayName;
                }

                return dto;
            }
            catch (Exception ex)
            {
                if (spesa != null)
                {
                    
                    _log.Error("Errore nel caricamento del riparto spese per unità - " + Library.Utility.GetMethodDescription() + " - id:" + spesa.ID, ex);
                }
                else
                {
                    
                    _log.Error("Errore nel caricamento del riparto spese per unità - " + Library.Utility.GetMethodDescription() + " - Spesa --> null", ex);
                }
                throw;
            }
        }
Exemple #8
0
 public virtual IUpdatableBusinessEntity Copy()
 {
     var spesa = new SpeseUnita(Importo, UnitaRiferimento, SoggettoCondominio, MovimentoRiferimento);
     return spesa;
 }
        private string setRipartoBolletta(Spesa spesa, IList<ImportiDTO> addebitiCalcolati, Conto contoMillesimiSpalo, decimal importoTotaleBollette, IList<RipartoBollette> calcoli, IList<SoggettoCondominio> soggettiAttivi)
        {
            try
            {
                var message = string.Empty;

                spesa.IsRipartita = true;

                // ==================================================
                //  Calcolo il riparto
                // ==================================================
                var importoTotaleAddebitato = addebitiCalcolati.Sum(item => item.Importo);
                var index = 0;
                foreach (var movimento in spesa.MovimentiBollette)
                {
                    try
                    {
                        foreach (var speseUnita in movimento.DettaglioRipartizione)
                            speseUnita.MovimentoRiferimento = null;
                        movimento.DettaglioRipartizione.Clear();

                        // Individuo quali sono i consumi da considerare
                        //var addebitiCalcolatiDaConsiderare = addebitiCalcolati.Where(importoPerUnita => movimento.DettaglioRipartizione.Any(item => item.UnitaRiferimento.ID == importoPerUnita.Id)).ToList();
                        var unitaDaConsiderare = GetUnitaContoModello(movimento, index);
                        var addebitiCalcolatiDaConsiderare = addebitiCalcolati.Where(importoPerUnita => unitaDaConsiderare.Any(item => item.ID == importoPerUnita.Id)).ToList();

                        var percentualeMovimento = (movimento.GetImportoConSegno().GetValueOrDefault() * 100) / importoTotaleBollette;
                        var importoMovimentoAddebitato = (importoTotaleAddebitato * percentualeMovimento) / 100;
                        var importoMovimentoSpalo = movimento.GetImportoConSegno().GetValueOrDefault() - importoMovimentoAddebitato;

                        // Calcolo il riparto per ogni unità
                        foreach (var importoPerUnita in addebitiCalcolati)
                        {
                            try
                            {
                                var unita = _daoFactory.GetUnitaImmobiliareDao().GetById(importoPerUnita.Id, false);

                                // Riparto importo addebitato
                                var importo = _millesimiService.GetRipartoImportoValori(unita, importoMovimentoAddebitato, addebitiCalcolatiDaConsiderare);

                                // Riparto spalo
                                if (contoMillesimiSpalo == null)
                                    importo += _millesimiService.GetRipartoImportoValori(unita, importoMovimentoSpalo, addebitiCalcolatiDaConsiderare);
                                else
                                    importo += _millesimiService.GetRipartoImporto(unita, contoMillesimiSpalo, importoMovimentoSpalo, null, spesa.EsercizioRiferimento).GetValueOrDefault();

                                // Aggiorno l'importo a Bilancio sul calcolo acqua
                                if (calcoli != null)
                                {
                                    var riparto = (from item in calcoli
                                                   where item.UnitaImmobiliare != null && item.UnitaImmobiliare.ID == importoPerUnita.Id
                                                   select item).SingleOrDefault();
                                    if (riparto != null)
                                        riparto.ImportoBilancio = riparto.ImportoBilancio.GetValueOrDefault() + importo;
                                }

                                // =======================================================================================
                                //  Riparto la spese tra tutti i condomini partecipanti nell'unità immobiliare
                                // =======================================================================================
                                // -------------------------
                                // Proprietario
                                // -------------------------
                                var proprietariPrincipali = (from item in soggettiAttivi
                                                                where
                                                                    item.Tipo == TipoSoggetto.Proprietario &&
                                                                    item.UnitaImmobiliare.ID == unita.ID &&
                                                                    item.Principale.GetValueOrDefault()
                                                                select item).ToList();
                                if (proprietariPrincipali.Count > 1)
                                {
                                    if (proprietariPrincipali.All(item => item.DataInizio == null) || proprietariPrincipali.All(item => item.DataFine == null))
                                        _log.Warn("Trovato più di un PROPRIETARIO principale - " + Library.Utility.GetMethodDescription() + " - idUnita: " + unita.ID + " - idEsercizio: " + movimento.Testata.EsercizioRiferimento.ID);
                                }

                                var proprietarioPrincipale = proprietariPrincipali.OrderByDescending(item => item.DataInizio.GetValueOrDefault()).FirstOrDefault(item => item.DataFine == null);

                                // Se il proprietario non è presente lo cerco tra tutti i proprietari
                                if (proprietarioPrincipale == null)
                                {
                                    proprietarioPrincipale = (from item in unita.Proprietari
                                                                where item.DataInizio == null || item.DataInizio.Value < movimento.Testata.EsercizioRiferimento.DataChiusura
                                                                orderby item.DataInizio.GetValueOrDefault() descending
                                                                select item).FirstOrDefault();
                                }

                                var importoConduzione = _ripartizioneSpeseService.GetImportoCompetenza(importo.GetValueOrDefault(), movimento, TipoSoggetto.Conduttore);
                                var importoProprieta = _ripartizioneSpeseService.GetImportoCompetenza(importo.GetValueOrDefault(), movimento, TipoSoggetto.Proprietario);

                                // --------------------------------------------
                                //  Importo di proprietà
                                // --------------------------------------------
                                if (importoProprieta != 0)
                                {
                                    var soggProp = new List<ImportiDTO>();

                                    // --------------------------------------------------------------------
                                    //  Individuo tutti i soggetti tra cui ripartire l'importo
                                    // --------------------------------------------------------------------
                                    var conto = movimento.ContoRiferimento;
                                    var soggPropRip = (from itemSogg in conto.SoggettiRipartizione
                                                       where itemSogg.Soggetto.Tipo == TipoSoggetto.Proprietario && itemSogg.Soggetto.UnitaImmobiliare.ID == unita.ID
                                                       select itemSogg).ToList();

                                    // In presenza di ripartizioni personalizzate occorre dividere l'importo addebito alla proprietà tra i diversi proprietari
                                    if (soggPropRip.Count > 0)
                                    {
                                        var totaleSoggPropRip = soggPropRip.Sum(item => item.PercentualeRipartizione);
                                        soggProp.AddRange(from sogg in soggPropRip
                                                          let soggettoRipartizione = sogg.Soggetto
                                                          select new ImportiDTO
                                                          {
                                                              Id = soggettoRipartizione.ID,
                                                              Importo = (importoProprieta * sogg.PercentualeRipartizione) / totaleSoggPropRip
                                                          });
                                    }
                                    else if (soggPropRip.Count == 0)
                                    {
                                        var proprietariAttivi = soggettiAttivi.Where(item => item.Tipo == TipoSoggetto.Proprietario && item.UnitaImmobiliare.ID == unita.ID).ToList();

                                        if (proprietariAttivi.Count == 0 && proprietarioPrincipale != null)
                                            proprietariAttivi.Add(proprietarioPrincipale);
                                        if (proprietariAttivi.Sum(item => item.PercentualeRiferimento) != 100)
                                        {
                                            if (proprietariAttivi.All(item => item.DataInizio == null) || proprietariAttivi.All(item => item.DataFine == null))
                                                _log.Warn("ATTENZIONE: La somma della percentuale di riparto non è 100 - " + Library.Utility.GetMethodDescription() + " (Spese - Proprietari) - idUnita:" + unita.ID + " - idSpesa: " + spesa.ID + " - idEsercizio: " + movimento.Testata.EsercizioRiferimento.ID);

                                            if (proprietariAttivi.Count == 1)
                                                proprietariAttivi[0].PercentualeRiferimento = 100m;
                                        }

                                        soggProp.AddRange(proprietariAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (importoProprieta * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 }));
                                    }

                                    foreach (var importiDTO in soggProp)
                                    {
                                        var soggetto = soggettiAttivi.FirstOrDefault(item => item.ID == importiDTO.Id) ?? _daoFactory.GetSoggettoCondominioDao().Find(importiDTO.Id, false);
                                        var spesaUnita = new SpeseUnita(importiDTO.Importo, null, soggetto, movimento);
                                        _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaUnita);
                                    }

                                }

                                // --------------------------------------------
                                //  Importo di conduzione
                                // --------------------------------------------
                                if (importoConduzione > 0)
                                {
                                    var soggCond = new List<ImportiDTO>();

                                    var soggCondRip = (from itemSogg in movimento.ContoRiferimento.SoggettiRipartizione
                                                        where
                                                            itemSogg.Soggetto.Tipo == TipoSoggetto.Conduttore &&
                                                            itemSogg.Soggetto.UnitaImmobiliare.ID == unita.ID
                                                        select itemSogg).ToList();

                                    if (soggCondRip.Count > 0)
                                    {
                                        var totaleSoggCondRip = soggCondRip.Sum(item => item.PercentualeRipartizione);
                                        soggCond.AddRange(soggCondRip.Select(sogg => new ImportiDTO
                                        {
                                            Id = sogg.Soggetto.ID,
                                            Importo = (importoConduzione * sogg.PercentualeRipartizione) / totaleSoggCondRip
                                        }));
                                    }
                                    else if (soggCondRip.Count == 0)
                                    {
                                        var conduttoriAttivi = (from item in soggettiAttivi
                                                                where item.Tipo == TipoSoggetto.Conduttore && item.UnitaImmobiliare.ID == unita.ID
                                                                select item).ToList();
                                        if (!conduttoriAttivi.Any())
                                        {
                                            conduttoriAttivi = (from item in soggettiAttivi
                                                                where item.Tipo == TipoSoggetto.Proprietario && item.UnitaImmobiliare.ID == unita.ID
                                                                select item).ToList();
                                        }

                                        if (conduttoriAttivi.Sum(item => item.PercentualeRiferimento) != 100)
                                        {

                                            _log.Warn("ATTENZIONE: La somma della percentuale di riparto non è 100 - " + Library.Utility.GetMethodDescription() + " (Spese - Conduttori) - idUnita:" + unita.ID + " - idSpesa: " + spesa.ID + " - idEsercizio: " + movimento.Testata.EsercizioRiferimento.ID);

                                            if (conduttoriAttivi.Count == 1)
                                                conduttoriAttivi[0].PercentualeRiferimento = 100m;
                                        }

                                        soggCond.AddRange(conduttoriAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (importoConduzione * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 }));
                                    }

                                    foreach (var importiDTO in soggCond)
                                    {
                                        var soggetto = soggettiAttivi.FirstOrDefault(item => item.ID == importiDTO.Id) ?? _daoFactory.GetSoggettoCondominioDao().Find(importiDTO.Id, false);
                                        var spesaUnita = new SpeseUnita(importiDTO.Importo, null, soggetto, movimento);
                                        _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaUnita);
                                    }
                                }

                            }
                            catch (Exception ex)
                            {
                                
                                _log.Error("Errore durante la ripartizione di una bolletta - SINGOLA UNITA' - " + Library.Utility.GetMethodDescription() + " - unità:" + importoPerUnita.Id + " - movimento:" + movimento.ID + " - idBolletta:" + spesa.ID, ex);
                                throw;
                            }
                        }

                        index++;
                    }
                    catch (Exception ex)
                    {
                        
                        _log.Error("Errore durante la ripartizione di una bolletta - SINGOLO MOVIMENTO - " + Library.Utility.GetMethodDescription() + " - movimento:" + movimento.ID + " - idBolletta:" + spesa.ID, ex);
                        throw;
                    }
                }

                return message;
            }
            catch (Exception ex)
            {
                
                _log.Error("Errore durante la ripartizione di una bolletta - " + Library.Utility.GetMethodDescription() + " - idBolletta:" + spesa.ID, ex);
                throw;
            }
        }
        public void SalvaRipartizione(MovimentoContabile movimento, IList<ImportiDTO> importi, bool spesaPersonale)
        {
            foreach (var importo in importi)
            {
                SpeseUnita spesaUnita;
                if(!spesaPersonale)
                    spesaUnita = new SpeseUnita(importo.Importo, _daoFactory.GetUnitaImmobiliareDao().GetById(importo.Id, false), null, movimento);
                else
                    spesaUnita = new SpeseUnita(importo.Importo, null, _daoFactory.GetSoggettoCondominioDao().GetById(importo.Id, false), movimento);
                _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaUnita);
            }

        }
        public void SalvaRipartizione(MovimentoContabile movimento, int idCondominio, bool defaultSelezionato)
        {
            var lista = new List<SpeseUnita>(movimento.DettaglioRipartizione.Count);
            lista.AddRange(movimento.DettaglioRipartizione);
            foreach (var spesaOld in lista)
            {
                movimento.DettaglioRipartizione.Remove(spesaOld);
                spesaOld.MovimentoRiferimento = null;
            }

            var tb = GetUnitaDataSource(GetKey(movimento), movimento.ContoRiferimento.ID, idCondominio, defaultSelezionato, movimento.Testata.EsercizioRiferimento, false);
            foreach (DataRow row in tb.Rows)
            {
                if (row["Selezionato"] != DBNull.Value && (bool)row["Selezionato"])
                {
                    SpeseUnita spesaUnita;
                    if(row["IdUnitaImmobiliare"] != null && row["IdUnitaImmobiliare"] != DBNull.Value)
                        spesaUnita = new SpeseUnita(null, _daoFactory.GetUnitaImmobiliareDao().GetById((int)row["IdUnitaImmobiliare"], false), null, movimento);
                    else
                        spesaUnita = new SpeseUnita(null, null, _daoFactory.GetSoggettoCondominioDao().GetById((int)row["IdSoggettoCondominio"], false), movimento);
                    _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaUnita);
                }
            }
        }
        private void setRipartizione(MovimentoContabile movimento)
        {
            if (movimento.ContoRiferimento.Ripartizione && !movimento.ContoRiferimento.IsSpesePersonali)
            {
                if ((!movimento.IsRipartoPersonalizzato || !string.IsNullOrEmpty(movimento.GruppiAddebito)))
                {
                    movimento.DettaglioRipartizione.Clear();

                    List<int> idScale = null;
                    if (!string.IsNullOrEmpty(movimento.GruppiAddebito))
                    {
                        var scale = movimento.GruppiAddebito.Split('&');
                        idScale = new List<int>(scale.Length);
                        idScale.AddRange(scale.Select(int.Parse));
                    }

                    var millesimi = _millesimiService.GetByConto(movimento.ContoRiferimento, null, idScale, movimento.Testata.EsercizioRiferimento);
                    foreach (var millesimo in millesimi)
                    {
                        var unita = _daoFactory.GetUnitaImmobiliareDao().GetById(millesimo.IdUnitaRiferimento, false);
                        var valoreMillesimo = _millesimiService.GetRipartoImporto(unita, movimento.ContoRiferimento, movimento.GetImportoConSegno().GetValueOrDefault(), millesimi, movimento.Testata.EsercizioRiferimento, null);
                        if (valoreMillesimo != null)
                        {
                            var riparto = new SpeseUnita(valoreMillesimo, unita, null, movimento);
                            movimento.DettaglioRipartizione.Add(riparto);
                        }
                    }
                }
                else
                    RicalcoloRipartizioneByMovimento(movimento);
            }
            else
                RicalcoloRipartizioneByMovimento(movimento);
        }
        /// <summary>
        /// Restituisce l'importo di competenza di una spesa per un singolo soggetto
        /// </summary>
        /// <param name="spesa">Spesa addebitata all'intera unità immobiliare</param>
        /// <param name="tipoSoggetto">Tipo di soggetto per il quale si vuole calcolare l'importo di competenza</param>
        /// <param name="anno">Se definito l'importo è proporzionato alla percentuale di spesa effettivamente pagata, se non definito non viene usata tale proporzione.
        /// <remarks>Solo per il calcolo dell'importo di competenza per la stampa del bilancio per detrazioni 36 e 55 deve essere definito l'anno e quindi usata la proporzione relativa al pagamento della spesa</remarks>
        /// </param>
        /// <param name="detrazione">Detrazione da considerare</param>
        /// <returns>L'importo di competenza</returns>
        public decimal GetImportoCompetenza(SpeseUnita spesa, TipoSoggetto tipoSoggetto, int? anno, int? detrazione)
        { 
            decimal importoCompetenza = 0;

            if (spesa.GetImporto() != 0)
            {
                if (spesa.SoggettoCondominio != null)
                    return tipoSoggetto == spesa.SoggettoCondominio.Tipo ? spesa.GetImporto() * spesa.GetMovimentoRiferimento().GetPercentualePagata(anno, detrazione) : 0;

                var contoRiferimento = spesa.GetMovimentoRiferimento().ContoRiferimento;
                var sottoContoRiferimento = spesa.GetMovimentoRiferimento().SottoContoRiferimento;

                // ---------------------------------------------
                //  Calcolo percentuale proprietà
                // ---------------------------------------------
                var percentualeProprieta = spesa.GetMovimentoRiferimento().ContoRiferimento.PercentualeProprieta;

                if (sottoContoRiferimento?.PercentualeProprieta != null)
                    percentualeProprieta = sottoContoRiferimento.PercentualeProprieta.GetValueOrDefault();

                // Se definita devo usare la specifica ripartizione per spesa
                if (spesa.GetMovimentoRiferimento().PercentualeProprieta != null)
                    percentualeProprieta = spesa.GetMovimentoRiferimento().PercentualeProprieta.GetValueOrDefault();

                // Se è definita devo usare la ripartizione per conto
                if (contoRiferimento.SoggettiRipartizione.Any(item => item.Soggetto.UnitaImmobiliare.ID == spesa.UnitaRiferimento.ID))
                {
                    percentualeProprieta = (contoRiferimento.SoggettiRipartizione.Where(
                        item =>
                            item.Soggetto.Tipo == TipoSoggetto.Proprietario &&
                            item.Soggetto.UnitaImmobiliare.ID == spesa.UnitaRiferimento.ID)).Sum(item => item.PercentualeRipartizione);
                }

                // ---------------------------------------------
                //  Calcolo Importo Competenza
                // ---------------------------------------------
                var importoCompetenzaProprietario = spesa.GetImporto() * spesa.GetMovimentoRiferimento().GetPercentualePagata(anno, detrazione) * percentualeProprieta;

                if (tipoSoggetto == TipoSoggetto.Proprietario)
                    importoCompetenza = importoCompetenzaProprietario;
                else
                    importoCompetenza = spesa.GetImporto() * spesa.GetMovimentoRiferimento().GetPercentualePagata(anno, detrazione) - importoCompetenzaProprietario;
            }

            return importoCompetenza;
        }
        public void CloneRipartizioneByMovimento(MovimentoContabile movimentoNew, MovimentoContabile movimentoOld)
        {
            IList<MillesimoDTO> millesimi = new List<MillesimoDTO>();
            if(!movimentoOld.ContoRiferimento.IsSpesePersonali)
                millesimi = (from item in _millesimiService.GetByConto(movimentoOld.ContoRiferimento, null , null, movimentoOld.Testata.EsercizioRiferimento)
                             where
                             (
                                 from item2 in movimentoOld.DettaglioRipartizione
                                 where item2?.UnitaRiferimento != null
                                 select item2.UnitaRiferimento.ID
                             ).Contains(item.IdUnitaRiferimento)
                             select item).ToList();

            var count = movimentoOld.DettaglioRipartizione.Count;
            foreach (var spesaUnita in movimentoOld.DettaglioRipartizione)
            {
                decimal? importo = 0;
                if (movimentoOld.ContoRiferimento.IsSpesePersonali)
                    importo = movimentoNew.GetImportoConSegno() / count;
                else if(spesaUnita.UnitaRiferimento != null)
                    importo = _millesimiService.GetRipartoImporto(spesaUnita.UnitaRiferimento, movimentoOld.ContoRiferimento, movimentoNew.GetImportoConSegno().GetValueOrDefault(), millesimi, movimentoOld.Testata.EsercizioRiferimento, null);
                else
                    _log.WarnFormat("ATTENZIONE: trovato movimento NON di spese personali con dettaglio ripartizione senza unità definita - {0} - idSpesaUnita:{1} - idMovimentoInteressi:{2} - idMovimentoBase:{3}", Utility.GetMethodDescription(), spesaUnita.ID, movimentoNew.ID, movimentoOld.ID);

                if (importo > 0)
                {
                    var spesaNew = new SpeseUnita(importo, spesaUnita.UnitaRiferimento, spesaUnita.SoggettoCondominio, movimentoNew);
                    _daoFactory.GetSpeseUnitaDao().SaveOrUpdate(spesaNew);
                }
            }

            if (movimentoNew.Importo != movimentoNew.DettaglioRipartizione.Sum(item => item.Importo))
                _log.WarnFormat("ATTENZIONE: l'importo degli interessi/sanzione non corrisponde con con l'importo della ripartizione - {0} - idMovimentoInteressi:{1} - idMovimentoBase:{2} - importoInteressi:{3} - importoRipartizione:{4}", Utility.GetMethodDescription(), movimentoNew.ID, movimentoOld.ID, movimentoNew.Importo.GetValueOrDefault(), movimentoNew.DettaglioRipartizione.Sum(item => item.Importo).GetValueOrDefault());

        }