Beispiel #1
0
        private decimal getImporto(IRipartizioneSpesa movimento, int? idStabile, int? idScala, Dictionary<string, IList<MillesimoDTO>> millesimiConto, Esercizio esercizio, int? detrazione)
        {
            if (movimento.DettaglioRipartizione.Count == 0 || !string.IsNullOrEmpty(movimento.GruppiAddebito) || !string.IsNullOrEmpty(movimento.StabiliAddebito))
            {
                var key = movimento.ContoRiferimento.ID.ToString(CultureInfo.InvariantCulture);
                List<int> stabili = null;
                List<int> scale = null;
                if (!string.IsNullOrEmpty(movimento.StabiliAddebito))
                {
                    stabili = new List<int>();
                    key += "|" + movimento.StabiliAddebito;
                    stabili.AddRange(movimento.StabiliAddebito.Split('&').Select(int.Parse));
                }
                if (!string.IsNullOrEmpty(movimento.GruppiAddebito))
                {
                    scale = new List<int>();
                    key += "|" + movimento.GruppiAddebito;
                    scale.AddRange(movimento.GruppiAddebito.Split('&').Select(int.Parse));
                }

                IList<MillesimoDTO> millesimiTotali = null;
                if (millesimiConto.ContainsKey(key))
                    millesimiTotali = millesimiConto[key];
                if (millesimiTotali == null)
                    millesimiTotali = _millesimiService.GetByConto(movimento.ContoRiferimento, stabili, scale, esercizio);

                // ---------------------------------------------------------------------------------------------------------------------------------------------
                // se la scala o lo stabile a cui è stato addebitato il movimento non comprende lo stabile o la scala di riferimento devo scartare il movimento
                if ((idStabile != null || idScala != null) && (stabili != null || scale != null))
                {
                    if (idStabile != null && stabili != null && !stabili.Contains(idStabile.Value))
                        return 0;
                    else if (idStabile != null && scale != null)
                    {
                        var stabiliCheck = new List<int>();
                        foreach (var i in scale)
                        {
                            var scala = _daoFactory.GetGruppoStabileDao().Find(i, false);
                            if (scala != null)
                                stabiliCheck.Add(scala.PalazzinaRiferimento.ID);
                        }

                        if (!stabiliCheck.Contains(idStabile.Value))
                            return 0;
                    }
                    else if (idScala != null && stabili != null)
                    {
                        var scaleToCheck = new List<int>();
                        foreach (var i in stabili)
                        {
                            var stabile = _daoFactory.GetPalazzinaDao().Find(i, false);
                            if (stabile != null)
                                scaleToCheck.AddRange(stabile.GruppiStabile.Select(gruppoStabile => gruppoStabile.ID));

                            if (!scaleToCheck.Contains(idScala.Value))
                                return 0;
                        }
                    }
                    else if (idScala != null && !scale.Contains(idScala.Value))
                        return 0;
                }
                // ---------------------------------------------------------------------------------------------------------------------------------------------

                IList<MillesimoDTO> millesimiMovimento = null;
                if (idStabile != null)
                {
                    key = $"{movimento.ContoRiferimento.ID}|{idStabile}";
                    if (millesimiConto.ContainsKey(key))
                        millesimiMovimento = millesimiConto[key];
                    if (millesimiMovimento == null)
                    {
                        // bugid#7195
                        // Se il movimento haun addebito diretto su alcune scale, per calcolare i millesimi di riferimento per lo stabile selezionato devo utilizzare
                        // SOLO le scale con addebito del movimento presenti nello stabile selezionato.
                        // Usando l'intero stabile i calcoli non sono corretti perchè sono considerate anche scale a cui NON è stato addebitato il movimento
                        if(!string.IsNullOrEmpty(movimento.StabiliAddebito) || scale == null)
                            millesimiMovimento = _millesimiService.GetByConto(movimento.ContoRiferimento, new List<int> { idStabile.Value }, null, esercizio);
                        else
                        {
                            var scaleMovimento = new List<int>();
                            foreach (var i in scale)
                            {
                                var scala = _daoFactory.GetGruppoStabileDao().Find(i, false);
                                if(scala != null && scala.PalazzinaRiferimento.ID == idStabile.Value)
                                    scaleMovimento.Add(i);
                                millesimiMovimento = _millesimiService.GetByConto(movimento.ContoRiferimento, null, scaleMovimento, esercizio);
                            }
                        }
                    }
                }

                if (idScala != null)
                {
                    key = $"{movimento.ContoRiferimento.ID}|{idScala}";
                    if (millesimiConto.ContainsKey(key))
                        millesimiMovimento = millesimiConto[key];
                    if (millesimiMovimento == null)
                        millesimiMovimento = _millesimiService.GetByConto(movimento.ContoRiferimento, null, new List<int> { idScala.Value }, esercizio);
                }

                if (millesimiMovimento != null)
                {
                    var denominatore = millesimiTotali.Sum(item => item.Valore.GetValueOrDefault());
                    var numeratore = millesimiMovimento.Sum(item => item.Valore.GetValueOrDefault());
                    if (denominatore != 0)
                        return (movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault() * numeratore) / denominatore;
                    else if (millesimiMovimento.Sum(item => item.Valore.GetValueOrDefault()) == 0)
                        return movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault();
                    else
                    {
                        throw new InvalidDataException($"La somma totale dei millesimi è 0 mentre la somma dei millesimi conti è <> 0 - {Utility.GetMethodDescription()} - esercizio:{esercizio?.ID.ToString() ?? "<NULL>"}");
                    }
                }                
            }
            else if (movimento.DettaglioRipartizione.Count > 0 && (idStabile != null || idScala != null))
            {
                var importo = 0m;
                foreach (var spesaUnita in movimento.DettaglioRipartizione)
                {
                    UnitaImmobiliare unita = null;
                    if (spesaUnita.UnitaRiferimento != null)
                        unita = spesaUnita.UnitaRiferimento;
                    else if (spesaUnita.SoggettoCondominio != null)
                        unita = spesaUnita.SoggettoCondominio.UnitaImmobiliare;

                    if(unita != null)
                    {
                        if (idStabile != null && unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID == idStabile.Value)
                            importo += spesaUnita.GetImporto();
                        else if (idScala != null && unita.GruppoStabileRiferimento.ID == idScala.Value)
                            importo += spesaUnita.GetImporto();
                    }
                }

                return importo;
            }

            return movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault();
        }
        private IEnumerable<SpeseUnitaRipartoDTO> getRiparto(IRipartizioneSpesa movimento, List<IGrouping<int, Millesimo>> millesimiGroupByConto, int? anno, int? detrazione, Esercizio esercizio, bool dettaglioSottoConto)
        {
            try
            {
                var importoProprieta = _ripartizioneService.GetImportoCompetenza(movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault(), movimento, TipoSoggetto.Proprietario, anno, detrazione);
                var importoConduzione = _ripartizioneService.GetImportoCompetenza(movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault(), movimento, TipoSoggetto.Conduttore, anno, detrazione);

                var millesimiConto = millesimiGroupByConto.Where(item => item.Key == movimento.ContoRiferimento.ID).ToList();
                var millesimiAttivi = new List<Millesimo>(millesimiConto.Count);
                foreach (var millesimoConto in millesimiConto)
                {
                    try
                    {
                        var millesimiGroupByUnita = millesimoConto.GroupBy(item => item.UnitaRiferimento.ID).ToList();
                        foreach (var spesa in movimento.DettaglioRipartizione)
                        {
                            try
                            {
                                IGrouping<int, Millesimo> millesimi = null;
                                if (spesa.UnitaRiferimento != null)
                                    millesimi = millesimiGroupByUnita.FirstOrDefault(item => item.Key == spesa.UnitaRiferimento.ID);
                                else if (spesa.SoggettoCondominio != null)
                                    millesimi = millesimiGroupByUnita.FirstOrDefault(item => item.Key == spesa.SoggettoCondominio.UnitaImmobiliare.ID);

                                if (millesimi != null)
                                    millesimiAttivi.AddRange(millesimi.ToList());
                            }
                            catch (Exception ex)
                            {
                                _log.ErrorFormat("Errore nel calcolo del riparto - SINGOLA SPESA - {0} - movimento:{1} - anno:{2} - esercizio:{3} - spesa:{4}", ex, Utility.GetMethodDescription(), movimento?.ID.ToString() ?? "<NULL>", anno.GetValueOrDefault(), esercizio?.ID.ToString() ?? "<NULL>", spesa?.ID.ToString() ?? "<NULL>");
                                throw;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.ErrorFormat("Errore nel calcolo del riparto - SINGOLO CONTO - {0} - movimento:{1} - anno:{2} - esercizio:{3} - conto:{4}", ex, Utility.GetMethodDescription(), movimento?.ID.ToString() ?? "<NULL>", anno.GetValueOrDefault(), esercizio?.ID.ToString() ?? "<NULL>", millesimoConto.Key);
                        throw;
                    }
                }

                IList<SpeseUnitaRipartoDTO> lista = new List<SpeseUnitaRipartoDTO>();
                if (millesimiAttivi.Count > 0)
                {
                    var totaleMillesimi = millesimiAttivi.Sum(item => item.Valore);
                    if (totaleMillesimi > 0)
                    {
                        foreach (var millesimo in millesimiAttivi)
                        {
                            // Se è definita devo usare la ripartizione specifica per conto
                            // ---------------------------------------------------------------------------------
                            var importoProprietario = (importoProprieta * millesimo.Valore) / totaleMillesimi;
                            var importoConduttore = (importoConduzione * millesimo.Valore) / totaleMillesimi;
                            var importi = getImportoProprietaConduzioneByUnita(movimento.ContoRiferimento, importoProprietario, importoConduttore, millesimo.UnitaRiferimento.ID);

                            var riparto = new SpeseUnitaRipartoDTO
                            {
                                IdConto = movimento.ContoRiferimento.ID,
                                IdUnita = millesimo.UnitaRiferimento.ID,
                                ValoreMillesimo = millesimo.Valore,
                                UnitaMisuraMillesimo = "PC",
                                ImportoProprietario = importi[0],
                                ImportoConduttore = importi[1]
                            };

                            if (dettaglioSottoConto)
                            {
                                if (movimento.SottoContoRiferimento != null)
                                    riparto.IdSottoConto = movimento.SottoContoRiferimento.ID;
                                else
                                    riparto.IdSottoConto = movimento.ID*-1;
                            }

                            lista.Add(riparto);
                        }
                    }
                    else
                    {
                        _log.WarnFormat("Totale millesimi a 0 - {0} - movimento:{1} - esercizio:{2} - anno:{3} - azienda:{4}", Utility.GetMethodDescription(), movimento.ID.ToString(), esercizio?.ID.ToString(CultureInfo.InvariantCulture) ?? "<NULL>", anno, esercizio?.CondominioRiferimento.Azienda.ID.ToString(CultureInfo.InvariantCulture) ?? "<NULL>");
                    }
                }
                else
                {
                    var millesimiAttiviDto = _millesimiService.GetByConto(movimento.ContoRiferimento, null, null, esercizio);
                    var totaleMillesimi = millesimiAttiviDto.Sum(item => item.Valore.GetValueOrDefault());
                    if (totaleMillesimi > 0)
                    {
                        foreach (var millesimo in millesimiAttiviDto)
                        {
                            // Se è definita devo usare la ripartizione specifica per conto
                            // ---------------------------------------------------------------------------------
                            var importoProprietario = (importoProprieta * millesimo.Valore) / totaleMillesimi;
                            var importoConduttore = (importoConduzione * millesimo.Valore) / totaleMillesimi;
                            var importi = getImportoProprietaConduzioneByUnita(movimento.ContoRiferimento, importoProprietario, importoConduttore, millesimo.IdUnitaRiferimento);

                            var riparto = new SpeseUnitaRipartoDTO
                            {
                                IdConto = movimento.ContoRiferimento.ID,
                                IdUnita = millesimo.IdUnitaRiferimento,
                                ValoreMillesimo = millesimo.Valore,
                                UnitaMisuraMillesimo = "PC",
                                ImportoProprietario = importi[0],
                                ImportoConduttore = importi[1]
                            };

                            if (dettaglioSottoConto)
                            {
                                if (movimento.SottoContoRiferimento != null)
                                    riparto.IdSottoConto = movimento.SottoContoRiferimento.ID;
                                else
                                    riparto.IdSottoConto = movimento.ID * -1;
                            }

                            lista.Add(riparto);
                        }
                    }
                    else
                    {
                        _log.WarnFormat("Totale millesimi a 0 - {0} - movimento:{1} - esercizio:{2} - anno:{3} - azienda:{4}", Utility.GetMethodDescription(), movimento.ID.ToString(), esercizio?.ID.ToString(CultureInfo.InvariantCulture) ?? "<NULL>", anno, esercizio?.CondominioRiferimento.Azienda.ID.ToString(CultureInfo.InvariantCulture) ?? "<NULL>");
                    }
                }

                return lista;
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore nel calcolo del riparto - {0} - movimento:{1} - anno:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), movimento?.ID.ToString() ?? "<NULL>", anno.GetValueOrDefault(), esercizio?.ID.ToString() ?? "<NULL>");
                throw;
            }
        }
        public decimal GetImportoCompetenza(decimal? importo, GruppoStabile gruppo, IRipartizioneSpesa movimento, List<int> stabili, List<int> gruppi, TipoSoggetto tipoSoggetto, int? anno, int? detrazione)
        {
            if (importo == null)
                importo = movimento.GetImportoConSegno(detrazione != null).GetValueOrDefault();

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

            var contoRiferimento = movimento.ContoRiferimento;

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

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