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); }