private ReportRipartizioneBilancioDTO cloneItem(ReportRipartizioneBilancioDTO item) { var clonedItem = new ReportRipartizioneBilancioDTO { IdRendiconto = item.IdRendiconto, IdConto = item.IdConto, CodiceConto = item.CodiceConto, DescrizioneConto = item.DescrizioneConto, IdSottoConto = item.IdSottoConto, CodiceSottoConto = item.CodiceSottoConto, DescrizioneSottoConto = item.DescrizioneSottoConto, IdPartecipante = item.IdPartecipante, DataUscitaPartecipante = item.DataUscitaPartecipante, OrdinePartecipante = item.OrdinePartecipante, IdPersona = item.IdPersona, IdUnitaImmobiliare = item.IdUnitaImmobiliare, TipoUnitaImmobiliare = item.TipoUnitaImmobiliare, IdGruppoStabile = item.IdGruppoStabile, DescrizioneGruppoStabile = item.DescrizioneGruppoStabile, OrdineGruppoStabile = item.OrdineGruppoStabile, IdStabile = item.IdStabile, DescrizioneStabile = item.DescrizioneStabile, OrdineStabile = item.OrdineStabile, OrdineUnitaImmobiliare = item.OrdineUnitaImmobiliare, SubalternoUnitaImmobiliare = item.SubalternoUnitaImmobiliare, PianoUnitaImmobiliare = item.PianoUnitaImmobiliare, InternoUnitaImmobiliare = item.InternoUnitaImmobiliare, Importo = item.Importo, Millesimi = item.Millesimi, Nominativo = item.Nominativo, NumeroColonne = item.NumeroColonne, OrdineConto = item.OrdineConto, TipoNominativo = item.TipoNominativo, TipoNominativoEffettivo = item.TipoNominativoEffettivo, DisabilitaStampaMillesimi = item.DisabilitaStampaMillesimi }; return clonedItem; }
public override IEnumerable<ReportRipartizioneBilancioDTO> GetDataSourceRipartizioneBilancioConsuntivo(int? idEsercizio, int? idCondominio, int? anno, int? detrazione, IList<int> idSpese, int? idStabile, int? idScala, bool ripartizioneProprietarioConduttore, bool accorpamentoUnita, TipoAccorpamentoRateEnum tipoAccorpamento, bool inversioneSaldi, bool calcoloPerSubentro, bool addebitiCondominio, bool addebitiDirettiStabileScala, IList<int> idSoggetti, bool dettaglioSottoConto = false) { try { var lista = new Dictionary<string, ReportRipartizioneBilancioDTO>(); Esercizio esercizio = null; Condominio condominio = null; // ============================================================================================= // Allineo flag di ripartizione personalizzata // ============================================================================================= if (idEsercizio != null) { try { _daoFactory.GetMovimentoContabileDao().ExecuteQuery("AllineamentoRipartoPersonalizzato", new QueryParam("idEsercizio", idEsercizio.GetValueOrDefault())); } catch (Exception ex) { _log.ErrorFormat("Errore nella esecuzione dell'allineamento personalizzato - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio.GetValueOrDefault()); } } var detrazioneRicerca = _ripartizioneService.GetDetrazioneRicerca(detrazione.GetValueOrDefault()); IList<Conto> contiChiusuraStraordinario = new List<Conto>(); if (idEsercizio != null) { esercizio = _daoFactory.GetEsercizioDao().Find(idEsercizio.Value, false); if (esercizio == null) { _log.WarnFormat("Esercizio non più presente - {0} - esercizio:{1}", Utility.GetMethodDescription(), idEsercizio.GetValueOrDefault()); return new BindingList<ReportRipartizioneBilancioDTO>(); } condominio = esercizio.CondominioRiferimento; contiChiusuraStraordinario = getContiEconomiciChiusuraStraordinario(condominio.ID); } // ============================================================================================= // Per gli esercizi chiusi deve essere proposto, se possibile, lo storico // ============================================================================================= if (esercizio != null && esercizio.Stato == StatoEsercizioEnum.Chiuso) { var listaStorico = getStoricoRiparto(esercizio.ID, idStabile, idScala, false, TipoRendiconto.Consuntivo); if (listaStorico.Any()) { if (!inversioneSaldi) { foreach (var reportRipartizioneBilancioDTO in listaStorico) { if (reportRipartizioneBilancioDTO.OrdineConto == 9993 || reportRipartizioneBilancioDTO.OrdineConto == 9994) reportRipartizioneBilancioDTO.Importo = reportRipartizioneBilancioDTO.Importo * -1; } } listaStorico = elaboraAccorpamento(listaStorico, tipoAccorpamento, condominio.GetSoggetti(esercizio.DataApertura.GetValueOrDefault(), null, null).ToList(), new Dictionary<int, IList<MillesimoDTO>>(), esercizio, null, null); return elaboraRigheContiVuoti(listaStorico); } } // ============================================================================================= // Ricalcolo i saldi solo se ho un esercizio precedente aperto // ============================================================================================= if (esercizio != null) { var esercizioPrecedente = esercizio.GetEsercizioPrecedente(); if (esercizioPrecedente != null && esercizioPrecedente.Stato == StatoEsercizioEnum.Aperto) _saldoContabileService.TrasferimentoSaldiNuovoEsercizio(esercizio.ID, this, calcoloPerSubentro); } if (idCondominio != null) condominio = _daoFactory.GetCondominioDao().GetById(idCondominio.Value, false); ImpostazioniAzienda impostazioni = null; IList<SoggettoCondominio> soggettiEsercizio = null; if (condominio != null) { impostazioni = _daoFactory.GetImpostazioniAziendaDao().GetByAzienda(condominio.Azienda.ID); soggettiEsercizio = esercizio != null ? _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizio(esercizio, null) : _daoFactory.GetSoggettoCondominioDao().GetAttiviByCondominioAnno(condominio.ID, anno.GetValueOrDefault()); } var conti = _daoFactory.GetContoDao().GetByCondominio(condominio.ID).ToDictionary(item => item.ID); // ------------------------------------------------------------------------------------------- // TODO: Da eliminare quando saranno riscritti i subentri - bugid#8425 var soggettiEsercizioNoSubentri = new List<SoggettoCondominio>(soggettiEsercizio.Count); foreach (var soggettoCondominio in soggettiEsercizio) { try { if (soggettoCondominio != null && soggettoCondominio.Tipo == TipoSoggetto.Proprietario || soggettoCondominio.DataInizio == null || (esercizio != null && soggettoCondominio.DataInizio.GetValueOrDefault() <= esercizio.DataApertura.GetValueOrDefault()) || (anno != null && soggettoCondominio.DataInizio.GetValueOrDefault().Year <= anno.Value)) soggettiEsercizioNoSubentri.Add(soggettoCondominio); } catch (Exception ex) { _log.ErrorFormat("Errore nella lettura dei soggetti per subentro - {0} - soggetto:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), soggettoCondominio?.ID, esercizio?.ID); } } // ------------------------------------------------------------------------------------------- IDictionary<int, IList<SoggettoCondominio>> soggettiAttivi = new Dictionary<int, IList<SoggettoCondominio>>(); foreach (var soggettoCondominioUnita in soggettiEsercizioNoSubentri.GroupBy(item => item.UnitaImmobiliare)) { soggettiAttivi.Add(soggettoCondominioUnita.Key.ID, soggettoCondominioUnita.ToList()); } IDictionary<int, SoggettoCondominio> soggettiAttiviIndex = new Dictionary<int, SoggettoCondominio>(); foreach (var soggettoCondominio in soggettiEsercizioNoSubentri) { soggettiAttiviIndex.Add(soggettoCondominio.ID, soggettoCondominio); } //==================================================================================== // Raggruppo gli importi dei movimenti per Conto, Sottoconto, Lotto, Stabile e Scala //==================================================================================== var importiConto = new List<ImportiContoSottocontoDTO>(); IList<IRipartizioneSpesa> movimenti; if (esercizio != null) { movimenti = _daoFactory.GetMovimentoContabileDao().GetByEsercizioEconomiciBilancio(esercizio).Cast<IRipartizioneSpesa>().ToList(); movimenti = movimenti.Where(item => item.Causale.Codice != "ST" || contiChiusuraStraordinario.Contains(item.ContoRiferimento)).ToList(); } else { var whereSpese = string.Empty; var parameters = new List<QueryParam>(3) { new QueryParam("condominio", condominio), new QueryParam("anno", anno), new QueryParam("detrazione", detrazioneRicerca) }; if (idSpese != null && idSpese.Count > 0) { whereSpese += " AND SPE in(:spese) "; parameters.Add(new QueryParam("spese", idSpese)); } const string hql = "FROM MovimentoContabile MOV LEFT JOIN FETCH MOV.FornitoreRiferimento FOR LEFT JOIN FETCH FOR.PersonaRiferimento PERS LEFT JOIN FETCH PERS.IndirizzoResidenza.Comune COM LEFT JOIN FETCH MOV.ContoRiferimento CON JOIN FETCH MOV.DettaglioRiferimento DETT JOIN FETCH DETT.SpesaRiferimento SPE LEFT JOIN FETCH SPE.RipartizioneSpesa RIPSPE LEFT JOIN FETCH SPE.Scadenze SCA LEFT JOIN FETCH SCA.Pagamenti PAG LEFT JOIN FETCH SPE.Riscossioni RISC LEFT JOIN FETCH RISC.MovimentoContabile MOVRISC LEFT JOIN FETCH MOVRISC.Testata TESRISC WHERE RIPSPE IS NULL AND MOV.Importo is not null AND MOV.Testata.EsercizioRiferimento.CondominioRiferimento = :condominio AND SPE.Detrazione = :detrazione AND (year(PAG.Data) = :anno OR year(TESRISC.DataRegistrazione) = :anno) {0}"; movimenti = _daoFactory.GetMovimentoContabileDao().GetByQuery(string.Format(hql, whereSpese), parameters.ToArray()).Cast<IRipartizioneSpesa>().ToList(); // Aggiungo le ripartizione relative a spese inserite solo fiscalmente if (detrazione != null) { const string hqlRipartzioni = "FROM RipartizioneSpesa RIPSPE LEFT JOIN FETCH RIPSPE.ContoRiferimento CON JOIN FETCH RIPSPE.Spesa SPE LEFT JOIN FETCH SPE.Scadenze SCA LEFT JOIN FETCH SCA.Pagamenti PAG WHERE RIPSPE.Importo is not null AND SPE.EsercizioRiferimento.CondominioRiferimento = :condominio AND SPE.Detrazione = :detrazione AND year(PAG.Data) = :anno {0}"; var ripartizioni = _daoFactory.GetRipartizioneSpesaDao().GetByQuery(string.Format(hqlRipartzioni, whereSpese), parameters.ToArray()).Cast<IRipartizioneSpesa>().ToList(); foreach (var ripartizioneSpesa in ripartizioni) { movimenti.Add(ripartizioneSpesa); } } } // NON considero le spese personali (NON sono soggette a riparto), le spese ripartite tramite letture del contatore (NON riparto lineare) e le spese con riparto personalizzato // ------------------------------------------------------------------------------------------------------------------------------------------------------ // TODO: Intevenire qui per poter gestire un riparto in cui a livello di modello sono mescolati addebiti a singoli stabili, scale e unità immobiliari // Per ogni scala, stabile e unità aggiungere un ImportiContoSottocontoDTO specifico ... fare molti test! // ------------------------------------------------------------------------------------------------------------------------------------------------------ foreach (var movimentoContabile in movimenti.Where(item => !item.GetContoRiferimento(detrazione != null).IsSpesePersonali && !item.IsRipartoPersonalizzato && (!item.RipartoTramiteLetture || item.DettaglioRipartizione.Count == 0) && (item.Spesa == null || item.Spesa.Utenza == null || !item.Spesa.Utenza.IsAllowRipartoLetture()))) { if (addebitiDirettiStabileScala) { if (idStabile != null && !isAddebitatoStabile(movimentoContabile, idStabile.Value)) continue; if (idScala != null && !isAddebitatoScala(movimentoContabile, idScala.Value)) continue; } else if (addebitiCondominio) { if (!string.IsNullOrEmpty(movimentoContabile.StabiliAddebito) || !string.IsNullOrEmpty(movimentoContabile.GruppiAddebito)) continue; } var contoRiferimento = movimentoContabile.GetContoRiferimento(detrazione != null); var sottoContoRiferimento = movimentoContabile.SottoContoRiferimento; int? idSottoConto = null; if (sottoContoRiferimento != null) idSottoConto = sottoContoRiferimento.ID; else if(dettaglioSottoConto) idSottoConto = movimentoContabile.ID*-1; int? idContatoreRiferimento = null; if (contoRiferimento.ContatoreRiferimento != null) idContatoreRiferimento = contoRiferimento.ContatoreRiferimento.ID; var stabili = new List<int>(); var scale = new List<int>(); if (!string.IsNullOrEmpty(movimentoContabile.StabiliAddebito)) stabili.AddRange(movimentoContabile.StabiliAddebito.Split('&').Select(int.Parse)); else if (!string.IsNullOrEmpty(movimentoContabile.GruppiAddebito)) scale.AddRange(movimentoContabile.GruppiAddebito.Split('&').Select(int.Parse)); if (stabili.Count > 0) { foreach (var id in stabili) { var importoConto = new ImportiContoSottocontoDTO { Conto = contoRiferimento.ID, SottoConto = idSottoConto, Stabile = id, ContatoreRiferimento = idContatoreRiferimento, ImportoProprieta = _ripartizioneService.GetImportoCompetenza(null, _daoFactory.GetPalazzinaDao().Find(id, false), movimentoContabile, null, null, TipoSoggetto.Proprietario, anno, detrazione), ImportoConduzione = _ripartizioneService.GetImportoCompetenza(null, _daoFactory.GetPalazzinaDao().Find(id, false), movimentoContabile, null, null, TipoSoggetto.Conduttore, anno, detrazione) }; addImporto(importoConto, importiConto); } } else if (scale.Count > 0) { foreach (var id in scale) { var importoConto = new ImportiContoSottocontoDTO { Conto = contoRiferimento.ID, SottoConto = idSottoConto, Scala = id, ContatoreRiferimento = idContatoreRiferimento, ImportoProprieta = _ripartizioneService.GetImportoCompetenza(null, _daoFactory.GetGruppoStabileDao().Find(id, false), movimentoContabile, null, null, TipoSoggetto.Proprietario, anno, detrazione), ImportoConduzione = _ripartizioneService.GetImportoCompetenza(null, _daoFactory.GetGruppoStabileDao().Find(id, false), movimentoContabile, null, null, TipoSoggetto.Conduttore, anno, detrazione) }; addImporto(importoConto, importiConto); } } else { var importoConto = new ImportiContoSottocontoDTO { Conto = contoRiferimento.ID, SottoConto = idSottoConto, ContatoreRiferimento = idContatoreRiferimento, ImportoProprieta = _ripartizioneService.GetImportoCompetenza(movimentoContabile.GetImportoConSegno(detrazione != null).GetValueOrDefault(), movimentoContabile, TipoSoggetto.Proprietario, anno, detrazione), ImportoConduzione = _ripartizioneService.GetImportoCompetenza(movimentoContabile.GetImportoConSegno(detrazione != null).GetValueOrDefault(), movimentoContabile, TipoSoggetto.Conduttore, anno, detrazione) }; addImporto(importoConto, importiConto); } } //==================================================================================== // Eseguo il riparto //==================================================================================== var listaMillesimi = _daoFactory.GetMillesimoDao().GetByCondominio(condominio.ID); var millesimiGroupByUnita = listaMillesimi.GroupBy(item => item.UnitaRiferimento.ID).ToList(); var millesimiGroupByConto = listaMillesimi.GroupBy(item => item.ContoRiferimento.ID).ToList(); var riparto = new Dictionary<string, SpeseUnitaRipartoDTO>(); var millesimiAttivi = new Dictionary<int, IList<MillesimoDTO>>(); foreach (var importiContoSottocontoDTO in importiConto) { if (importiContoSottocontoDTO.ContatoreRiferimento == null) { if (!listaMillesimi.Any() || listaMillesimi.Sum(item => item.Valore) == 0) continue; var spese = getRiparto(importiContoSottocontoDTO, millesimiGroupByConto, null, esercizio, dettaglioSottoConto); addSpeseToRiparto(spese, riparto, dettaglioSottoConto); } else { var conto = _daoFactory.GetContoDao().GetById(importiContoSottocontoDTO.Conto, false); List<int> stabili = null; if (importiContoSottocontoDTO.Stabile != null) stabili = new List<int> { importiContoSottocontoDTO.Stabile.GetValueOrDefault() }; List<int> scale = null; if (importiContoSottocontoDTO.Scala != null) scale = new List<int> { importiContoSottocontoDTO.Scala.GetValueOrDefault() }; IList<MillesimoDTO> millesimi; if (millesimiAttivi.ContainsKey(conto.ID)) millesimi = millesimiAttivi[conto.ID]; else { millesimi = _millesimiService.GetByConto(conto, stabili, scale, esercizio); millesimiAttivi.Add(conto.ID, millesimi); } var spese = getRiparto(conto, importiContoSottocontoDTO, millesimi, calcoloPerSubentro); addSpeseToRiparto(spese, riparto, dettaglioSottoConto); } } // Eseguo il riparto per le spese con riparto personalizzato ma che NON siano spese personali o spese ripartite tramite letture del contatore NON lineare (queste saranno considerate nel loop successivo) foreach (var movimentoContabile in movimenti.Where(item => item.IsRipartoPersonalizzato && !item.RipartoTramiteLetture && !item.GetContoRiferimento(detrazione != null).IsSpesePersonali && (item.Spesa?.Utenza == null || !item.Spesa.Utenza.IsAllowRipartoLetture()))) { var spese = getRiparto(movimentoContabile, millesimiGroupByConto, anno, detrazione, esercizio, dettaglioSottoConto); addSpeseToRiparto(spese, riparto, dettaglioSottoConto); } // Aggiungo le spese personali (NON sono soggette a riparto) e le spese ripartite tramite letture del contatore foreach (var movimentoContabile in movimenti.Where(item => (item.DettaglioRipartizione.Count > 0) && (item.GetContoRiferimento(detrazione != null).IsSpesePersonali || item.RipartoTramiteLetture || (item.Spesa?.Utenza != null && item.Spesa.Utenza.IsAllowRipartoLetture())))) { var contabile = movimentoContabile; var spese = movimentoContabile.DettaglioRipartizione.Select(spesa => new SpeseUnitaRipartoDTO { ID = spesa.ID, IdConto = contabile.GetContoRiferimento(detrazione != null).ID, IdSottoConto = contabile.SottoContoRiferimento?.ID ?? contabile.ID * -1, IdUnita = spesa.UnitaRiferimento?.ID, IdSoggettoCondominio = spesa.SoggettoCondominio?.ID, UnitaMisuraMillesimo = "PC", ImportoConduttore = _ripartizioneService.GetImportoCompetenza(spesa, TipoSoggetto.Conduttore, anno, detrazione), ImportoProprietario = _ripartizioneService.GetImportoCompetenza(spesa, TipoSoggetto.Proprietario, anno, detrazione) }); addSpeseToRiparto(spese, riparto, dettaglioSottoConto); } //===================================================================================================== // Elaborazione delle ripartizioni //===================================================================================================== foreach (var spesaAggregata in riparto.ToList()) { try { var spesa = spesaAggregata.Value; var conto = conti.ContainsKey(spesa.IdConto) ? conti[spesa.IdConto] : _daoFactory.GetContoDao().GetById(spesa.IdConto, false); SottoConto sottoconto = null; if (dettaglioSottoConto && spesa.IdSottoConto > 0) sottoconto = conto.SottoConti.FirstOrDefault(item => item.ID == spesa.IdSottoConto.Value); UnitaImmobiliare unita = null; SoggettoCondominio soggetto = null; if (spesa.IdUnita != null) unita = findUnitaImmobiliare(spesa.IdUnita.GetValueOrDefault(), soggettiAttivi); if (spesa.IdSoggettoCondominio != null) soggetto = findSoggettoCondominio(spesa.IdSoggettoCondominio.GetValueOrDefault(), soggettiAttiviIndex); // ------------------------------------------------------- // Verifica se appartiene a scala e/o stabile selezionato // ------------------------------------------------------- SoggettoCondominio proprietarioPrincipale = null; SoggettoCondominio conduttorePrincipale = null; // Se il soggetto è diverso da null individuo immediatamente il proprietario o il conduttore principale if (soggetto != null) { unita = soggetto.UnitaImmobiliare; if (!accorpamentoUnita) { switch (soggetto.Tipo) { case TipoSoggetto.Proprietario: proprietarioPrincipale = soggetto; break; case TipoSoggetto.Conduttore: conduttorePrincipale = soggetto; break; } } } if (idStabile != null) { if (unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID != idStabile.Value) continue; } if (idScala != null) { if (unita.GruppoStabileRiferimento.ID != idScala.Value) continue; } // ------------------------- // Proprietario // ------------------------- if (proprietarioPrincipale == null) { try { if (soggettiAttivi.ContainsKey(unita.ID)) { var proprietariPrincipali = (soggettiAttivi[unita.ID].Where(item => item.Tipo == TipoSoggetto.Proprietario && item.Principale.GetValueOrDefault())).ToList(); if (proprietariPrincipali.Count > 1) { if (proprietariPrincipali.All(item => item.DataInizio == null) || proprietariPrincipali.All(item => item.DataFine == null)) _log.DebugFormat("Trovato più di un PROPRIETARIO principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), spesa.IdUnita, idEsercizio); } proprietarioPrincipale = proprietariPrincipali.OrderByDescending(item => item.DataInizio.GetValueOrDefault()).FirstOrDefault(item => item.DataFine == null); } } catch (Exception ex) { _log.ErrorFormat("Errore nella ricerca del proprietario principale - {0} - unita:{1}", ex, Utility.GetMethodDescription(), unita.ID); throw; } } if (conduttorePrincipale == null) { if (soggettiAttivi.ContainsKey(unita.ID)) { var conduttoriPrincipale = (soggettiAttivi[unita.ID].Where(item => item.Tipo == TipoSoggetto.Conduttore && item.Principale.GetValueOrDefault())).ToList(); if (conduttoriPrincipale.Count > 1) _log.WarnFormat("Trovato più di un CONDUTTORE principale - {0} - idUnita:{1} - esercizio:{2}", Utility.GetMethodDescription(), spesa.IdUnita, idEsercizio); conduttorePrincipale = conduttoriPrincipale.FirstOrDefault(); } } // Se il proprietario non è presente lo cerco tra tutti i proprietari if (proprietarioPrincipale == null) { var dataLimite = DateTime.Today; if (esercizio != null) dataLimite = esercizio.DataChiusura.GetValueOrDefault(); else if (anno != null) dataLimite = new DateTime(anno.GetValueOrDefault(), 12, 31); proprietarioPrincipale = (unita.Proprietari.Where(item => item.DataInizio == null || item.DataInizio.Value < dataLimite) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); if (proprietarioPrincipale != null && !soggettiAttiviIndex.ContainsKey(proprietarioPrincipale.ID)) { if (soggettiAttivi.ContainsKey(proprietarioPrincipale.UnitaImmobiliare.ID)) soggettiAttivi[proprietarioPrincipale.UnitaImmobiliare.ID].Add(proprietarioPrincipale); else soggettiAttivi.Add(proprietarioPrincipale.UnitaImmobiliare.ID, new List<SoggettoCondominio>() { proprietarioPrincipale }); } } var importoProprieta = spesa.ImportoProprietario; if (importoProprieta == null) { _log.ErrorFormat("ATTENZIONE: Importo a null - {0} - id:{1} - conto:{2} - soggetto:{3} - unità:{4}", Utility.GetMethodDescription(), spesa.ID, spesa.IdConto, spesa.IdSoggettoCondominio, spesa.IdUnita); throw new InvalidDataException( $"Per il conto '{conto.Descrizione}' la ripartizione personalizzata dell'unità immobiliare '{unita.Ordine} - {unita.Descrizione}' non è corretta."); } if (importoProprieta.GetValueOrDefault() != 0) { var soggProp = new List<ImportiDTO>(); if (spesa.IdUnita != null) { if (!accorpamentoUnita) { // -------------------------------------------------------------------- // Individuo tutti i soggetti tra cui ripartire l'importo // -------------------------------------------------------------------- var soggPropRip = (conto.SoggettiRipartizione.Where(itemSogg => itemSogg.Soggetto.Tipo == TipoSoggetto.Proprietario && itemSogg.Soggetto.UnitaImmobiliare.ID == spesa.IdUnita)).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.GetValueOrDefault() * sogg.PercentualeRipartizione) / totaleSoggPropRip }); } else if (soggPropRip.Count == 0) { var spesa1 = spesa; IList<SoggettoCondominio> proprietariAttivi = new List<SoggettoCondominio>(); if (soggettiAttivi.ContainsKey(spesa1.IdUnita.GetValueOrDefault())) proprietariAttivi = soggettiAttivi[spesa1.IdUnita.GetValueOrDefault()].Where(item => item.Tipo == TipoSoggetto.Proprietario).ToList(); else _log.WarnFormat("Non trovato nessun condomino per l'unità immobiliare - {0} - unità:{1} - condominio:{2} - azienda:{3}", Utility.GetMethodDescription(), spesa1.IdUnita, idCondominio, condominio.Azienda.ID); 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.WarnFormat("ATTENZIONE: La somma della percentuale di riparto non è 100 - SPESE PROPRIETARI - {0} - unità:{1} - spesa:{2} - esercizio:{3}", Utility.GetMethodDescription(), spesa.IdUnita, spesa.ID, idEsercizio); if (proprietariAttivi.Count == 1) proprietariAttivi[0].PercentualeRiferimento = 100m; } soggProp.AddRange(proprietariAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (importoProprieta.GetValueOrDefault() * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 })); } } else soggProp.Add(new ImportiDTO(proprietarioPrincipale.ID, importoProprieta.GetValueOrDefault())); } else soggProp.Add(new ImportiDTO(proprietarioPrincipale.ID, importoProprieta.GetValueOrDefault())); foreach (var idSogg in soggProp) { try { if (idSogg.Importo != 0 && proprietarioPrincipale != null) { var key = getKey(spesa.IdConto, spesa.IdSottoConto, proprietarioPrincipale.UnitaImmobiliare.ID, idSogg.Id, accorpamentoUnita, TipoSoggetto.Proprietario, dettaglioSottoConto); ReportRipartizioneBilancioDTO item; if (lista.ContainsKey(key)) item = lista[key]; else { item = new ReportRipartizioneBilancioDTO(); lista.Add(key, item); item.Importo = 0; item.IdConto = spesa.IdConto; item.DisabilitaStampaMillesimi = conto.IsSpesePersonali || conto.DisabilitaMillesimiRiparto; var codice = string.Empty; if (conto.Codice != null) codice = conto.Codice; item.CodiceConto = codice; if (dettaglioSottoConto) { var codiceSottoConto = string.Empty; var descrizioneSottoConto = string.Empty; if (sottoconto != null) { if (!string.IsNullOrEmpty(sottoconto.Codice)) codiceSottoConto = sottoconto.Codice; descrizioneSottoConto = sottoconto.Descrizione; } else if (spesa.IdSottoConto < 0) { var movimento = _daoFactory.GetMovimentoContabileDao().Find(spesa.IdSottoConto.GetValueOrDefault() * -1, false); if (movimento != null) descrizioneSottoConto = movimento.GetDescrizione(); } item.IdSottoConto = spesa.IdSottoConto; item.CodiceSottoConto = codiceSottoConto; item.DescrizioneSottoConto = descrizioneSottoConto; } item.DescrizioneConto = !string.IsNullOrEmpty(conto.DescrizioneBilancio) && !dettaglioSottoConto ? conto.DescrizioneBilancio : conto.Descrizione; item.OrdineConto = conto.Ordine; item.IdUnitaImmobiliare = proprietarioPrincipale.UnitaImmobiliare.ID; item.TipoUnitaImmobiliare = unita.TipoUnitaImmobiliare.Descrizione; item.IdGruppoStabile = unita.GruppoStabileRiferimento.ID; item.DescrizioneGruppoStabile = unita.GruppoStabileRiferimento.Descrizione; item.OrdineGruppoStabile = unita.GruppoStabileRiferimento.Ordine; item.IdStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID; item.DescrizioneStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Descrizione; item.OrdineStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Ordine; item.OrdineUnitaImmobiliare = unita.Ordine.GetValueOrDefault(); item.SubalternoUnitaImmobiliare = unita.Subalterno; item.PianoUnitaImmobiliare = unita.Piano; item.InternoUnitaImmobiliare = getInternoUnitaImmobiliare(unita); item.Millesimi = spesa.ValoreMillesimo; item.UnitaMisuraMillesimi = spesa.UnitaMisuraMillesimo; item.MillesimiProprieta = getUnitaMillProp(unita, millesimiGroupByUnita); if (!accorpamentoUnita) { var sogg = findSoggettoCondominio(idSogg.Id, soggettiAttiviIndex); item.Nominativo = sogg.DisplayName; item.IdPartecipante = sogg.ID; item.IdPersona = sogg.Persona.ID; } else { item.Nominativo = proprietarioPrincipale.UnitaImmobiliare.Descrizione; item.IdPartecipante = proprietarioPrincipale.ID; item.IdPersona = proprietarioPrincipale.Persona.ID; } item.DataUscitaPartecipante = getDataUscita(proprietarioPrincipale); item.OrdinePartecipante = 10; item.TipoNominativo = "PROP"; item.TipoNominativoEffettivo = findSoggettoCondominio(item.IdPartecipante, soggettiAttiviIndex).Tipo.ToString().Substring(0, 1); item.NumeroColonne = 1; } item.Importo += idSogg.Importo; } else { if (proprietarioPrincipale == null) { throw new InvalidDataException($"Per l'unità immobiliare {unita.Ordine} non è presente un proprietario principale"); } } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - (SPESE - PROPRIETARI) - {0} - idSogg:{1} - idSpesa:{2} - idEsercizio:{3}", ex, Utility.GetMethodDescription(), idSogg.Id, spesa.ID, idEsercizio); throw; } } } // ------------------------- // Conduttore // ------------------------- if (spesa.ImportoConduttore.GetValueOrDefault() != 0) { var soggCond = new List<ImportiDTO>(); int idUnita; if (spesa.IdUnita != null) { idUnita = spesa.IdUnita.GetValueOrDefault(); if (!accorpamentoUnita) { var soggCondRip = (conto.SoggettiRipartizione.Where(itemSogg => itemSogg.Soggetto.Tipo == TipoSoggetto.Conduttore && itemSogg.Soggetto.UnitaImmobiliare.ID == spesa.IdUnita)).ToList(); if (soggCondRip.Count > 0) { var totaleSoggCondRip = soggCondRip.Sum(item => item.PercentualeRipartizione); soggCond.AddRange(soggCondRip.Select(sogg => new ImportiDTO { Id = sogg.Soggetto.ID, Importo = (spesa.ImportoConduttore.GetValueOrDefault() * sogg.PercentualeRipartizione) / totaleSoggCondRip })); } else if (soggCondRip.Count == 0) { var conduttoriAttivi = (soggettiAttivi[spesa.IdUnita.GetValueOrDefault()].Where(item => item.Tipo == TipoSoggetto.Conduttore && item.PercentualeRiferimento > 0)).ToList(); if (!conduttoriAttivi.Any()) { var spesa1 = spesa; conduttoriAttivi = (soggettiAttivi[spesa1.IdUnita.GetValueOrDefault()].Where(item => item.Tipo == TipoSoggetto.Proprietario)).ToList(); } if (conduttoriAttivi.Sum(item => item.PercentualeRiferimento) != 100) { _log.WarnFormat("ATTENZIONE: La somma della percentuale di riparto non è 100 - SPESE CONDUTTORI - {0} - unità:{1} - spesa:{2} - esercizio:{3}", Utility.GetMethodDescription(), spesa.IdUnita, spesa.ID, idEsercizio); } soggCond.AddRange(conduttoriAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (spesa.ImportoConduttore.GetValueOrDefault() * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 })); } } else if (proprietarioPrincipale != null) soggCond.Add(new ImportiDTO(proprietarioPrincipale.ID, spesa.ImportoConduttore.GetValueOrDefault())); } else { if (conduttorePrincipale == null) { conduttorePrincipale = soggettiEsercizio.Where( item => item.UnitaImmobiliare.ID == proprietarioPrincipale.UnitaImmobiliare.ID && item.Tipo == TipoSoggetto.Conduttore) .OrderByDescending(item => item.Principale) .FirstOrDefault(); } if (conduttorePrincipale == null) conduttorePrincipale = _daoFactory.GetSoggettoCondominioDao().Find(spesa.IdSoggettoCondominio.GetValueOrDefault(), false); if (conduttorePrincipale != null) { soggCond.Add(new ImportiDTO(conduttorePrincipale.ID, spesa.ImportoConduttore.GetValueOrDefault())); idUnita = conduttorePrincipale.UnitaImmobiliare.ID; } else throw new InvalidDataException($"Per l'unità immobiliare {unita.Descrizione} il conduttore non è configurato correttamente.{Environment.NewLine}Si prega di verificare e rilanciare l'esecuzione."); } foreach (var idSogg in soggCond) { try { if (idSogg.Importo != 0) { var key = getKey(spesa.IdConto, spesa.IdSottoConto, idUnita, idSogg.Id, accorpamentoUnita, TipoSoggetto.Conduttore, dettaglioSottoConto); ReportRipartizioneBilancioDTO item; if (lista.ContainsKey(key)) item = lista[key]; else { item = new ReportRipartizioneBilancioDTO(); lista.Add(key, item); item.Importo = 0; item.IdConto = spesa.IdConto; item.DisabilitaStampaMillesimi = conto.IsSpesePersonali || conto.DisabilitaMillesimiRiparto; var codice = string.Empty; if (conto.Codice != null) codice = conto.Codice; item.CodiceConto = codice; item.DescrizioneConto = !string.IsNullOrEmpty(conto.DescrizioneBilancio) && !dettaglioSottoConto ? conto.DescrizioneBilancio : conto.Descrizione; item.OrdineConto = conto.Ordine; if (dettaglioSottoConto) { var codiceSottoConto = string.Empty; var descrizioneSottoConto = string.Empty; if (sottoconto != null) { if (!string.IsNullOrEmpty(sottoconto.Codice)) codiceSottoConto = sottoconto.Codice; descrizioneSottoConto = sottoconto.Descrizione; } else if (spesa.IdSottoConto < 0) { var movimento = _daoFactory.GetMovimentoContabileDao().Find(spesa.IdSottoConto.GetValueOrDefault()*-1, false); if (movimento != null) descrizioneSottoConto = movimento.GetDescrizione(); } item.IdSottoConto = spesa.IdSottoConto; item.CodiceSottoConto = codiceSottoConto; item.DescrizioneSottoConto = descrizioneSottoConto; } item.IdUnitaImmobiliare = idUnita; item.TipoUnitaImmobiliare = unita.TipoUnitaImmobiliare.Descrizione; item.IdGruppoStabile = unita.GruppoStabileRiferimento.ID; item.DescrizioneGruppoStabile = unita.GruppoStabileRiferimento.Descrizione; item.IdStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID; item.DescrizioneStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Descrizione; item.OrdineGruppoStabile = unita.GruppoStabileRiferimento.Ordine; item.OrdineStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Ordine; item.OrdineUnitaImmobiliare = unita.Ordine.GetValueOrDefault(); item.InternoUnitaImmobiliare = getInternoUnitaImmobiliare(unita); item.SubalternoUnitaImmobiliare = unita.Subalterno; item.PianoUnitaImmobiliare = unita.Piano; item.Millesimi = spesa.ValoreMillesimo; item.UnitaMisuraMillesimi = spesa.UnitaMisuraMillesimo; item.MillesimiProprieta = getUnitaMillProp(unita, millesimiGroupByUnita); if (!accorpamentoUnita) { var sogg = findSoggettoCondominio(idSogg.Id, soggettiAttiviIndex); item.DataUscitaPartecipante = getDataUscita(sogg); item.Nominativo = sogg.DisplayName; item.IdPartecipante = sogg.ID; item.IdPersona = sogg.Persona.ID; } else { item.DataUscitaPartecipante = getDataUscita(proprietarioPrincipale); item.Nominativo = proprietarioPrincipale.UnitaImmobiliare.Descrizione; item.IdPartecipante = proprietarioPrincipale.ID; item.IdPersona = proprietarioPrincipale.Persona.ID; } item.OrdinePartecipante = 20; item.TipoNominativo = "COND"; item.TipoNominativoEffettivo = ripartizioneProprietarioConduttore ? "C" : findSoggettoCondominio(item.IdPartecipante, soggettiAttiviIndex).Tipo.ToString().Substring(0, 1); item.NumeroColonne = 1; } item.Importo += idSogg.Importo; } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SPESE CONDUTTORI - {0} - soggetto:{1} - spesa:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), idSogg.Id, spesa.ID, idEsercizio); throw; } } } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - (SPESE) - {0} - idSpesa:{1} - esercizio:{2} - anno:{3} - detrazione:{4}", ex, Utility.GetMethodDescription(), spesaAggregata.Value.ID, idEsercizio.GetValueOrDefault(), anno.GetValueOrDefault(), detrazione.GetValueOrDefault()); throw; } } //============================================================================================================== // Elaborazione SUBENTRI per avere una riga per ogni soggetto //============================================================================================================== elaboraSubentri(esercizio, accorpamentoUnita, lista, soggettiAttivi, conti, dettaglioSottoConto); //============================================================================================================== // Calcolo totali spese //============================================================================================================== var totali = new Dictionary<string, ReportRipartizioneBilancioDTO>(); foreach (var itemGroup in lista.Values.GroupBy(item => item.IdPartecipante.ToString().PadLeft(10, '0') + "&" + item.TipoNominativo)) { try { var itemSpesa = itemGroup.FirstOrDefault(); var totaleKey = getKey(0, null, itemSpesa.IdUnitaImmobiliare, itemSpesa.IdPartecipante, accorpamentoUnita, itemSpesa.TipoNominativo == "PROP" ? TipoSoggetto.Proprietario : TipoSoggetto.Conduttore, dettaglioSottoConto); // Somma gli importi raggruppati per conto perchè deve arrotondare l'importo a livello di conto var groupConto = itemGroup.GroupBy(item => item.IdConto); var importoTotale = groupConto.Sum(itemGroupConto => Math.Round(itemGroupConto.Sum(item => item.Importo.GetValueOrDefault()), 2)); if (!totali.ContainsKey(totaleKey)) { var itemTotale = getItemTotale(itemSpesa); itemTotale.Importo = importoTotale; totali.Add(totaleKey, itemTotale); } else { var itemTotale = totali[totaleKey]; itemTotale.Importo += importoTotale; } } catch (Exception ex) { _log.ErrorFormat("Errore nel calcolo dei totali - SINGOLO TOTALE - {0} - key:{1}", ex, Utility.GetMethodDescription(), itemGroup.Key); throw; } } //============================================================================================================== // SOLO se NON si tratta di un riparto per DETRAZIONE //============================================================================================================== if (esercizio != null) { var versamenti = _versamentiCondominiService.GetImportoMovimentiVersatoByEsercizio(esercizio, idStabile, idScala); //============================================================================================================== // Ripartizione delle differenze tra Rendiconto e Riparto //============================================================================================================== // Merge var saldi = _daoFactory.GetSaldoSoggettoDao().GetByEsercizioStabileScala(esercizio, idStabile, idScala); var saldiCalcolati = new Dictionary<int, ReportRipartizioneBilancioDTO>(); var versamentiCalcolati = new List<int>(); var totaliCalcolati = new List<ReportRipartizioneBilancioDTO>(); // Se il soggetto non è presente nei totali (quindi non ha nessuna spesa addebitata) lo aggiungo con un elemento FAKE (666), che poi // provvederò a cancellare, per permettere l'inserimento degli elementi di saldo e versamenti // ---------------------------------------------------------------------------------------------------------------------------------- // Saldi foreach (var saldo in saldi) { try { totali = elaboraSoggetto(saldo.Soggetto, soggettiAttivi, totali, esercizio, accorpamentoUnita); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo (SALDI FAKE) - {0} - saldo:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), saldo.ID, idEsercizio); throw; } } // Versamenti foreach (var item in versamenti) { try { var soggetto = findSoggettoCondominio(item.Id, soggettiAttiviIndex); if (soggetto != null) { if (idStabile != null) { if (soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.ID != idStabile.Value) continue; } if (idScala != null) { if (soggetto.UnitaImmobiliare.GruppoStabileRiferimento.ID != idScala.Value) continue; } totali = elaboraSoggetto(soggetto, soggettiAttivi, totali, esercizio, accorpamentoUnita); } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo (VERSAMENTI FAKE) - {0} - soggetto:{1} - importo:{2:c} - esercizio:{3}", ex, Utility.GetMethodDescription(), item.Id, item.Importo, idEsercizio); throw; } } //============================================================================================================== // Elaborazione dei totali + saldi e versamenti //============================================================================================================== var partecipantiElaborati = new List<int>(); // Leggo i versamenti successivi alla chiusura solo per gli esercizi ordinari PianoRatealeDettaglio pianoRatealeDettaglio = null; if (esercizio.Gestione == GestioneEsercizioEnum.Ordinario) { var esercizioSuccessivo = _daoFactory.GetEsercizioDao().GetEsercizioCompetenza(esercizio.CondominioRiferimento, esercizio.DataChiusura.GetValueOrDefault().AddDays(1)); if (esercizioSuccessivo != null) pianoRatealeDettaglio = _daoFactory.GetPianoRatealeDettaglioDao().GetRataVersamentoDopoChiusura(esercizioSuccessivo); } foreach (var kvp in totali) { try { var soggetto = findSoggettoCondominio(kvp.Value.IdPartecipante, soggettiAttiviIndex); // Può capitare in caso di subentro senza trasferimento di saldi e versamenti lista.Add(kvp.Key, kvp.Value); // --------------------------------------------------------- // Saldo Anno Precedente // --------------------------------------------------------- var itemRiporto = new ReportRipartizioneBilancioDTO(); if (!saldiCalcolati.ContainsKey(kvp.Value.IdPartecipante)) { // Inserisco il saldo solo se diverso da 0, oppure se è relativo al proprietario principale. (bugid#999) // La riga del proprietario deve essere sempre presente anche se tutti gli importi sono a 0, il conduttore // invece non deve essere presente se gli importi sono a 0 int? idPartecipante = kvp.Value.IdPartecipante; int? idUnitaImmobiliare = null; if (accorpamentoUnita) { idPartecipante = null; idUnitaImmobiliare = kvp.Value.IdUnitaImmobiliare; } var saldo = getSaldoBySoggettoUnita(saldi, idPartecipante, idUnitaImmobiliare); if ((saldo != null && saldo != 0) || (kvp.Value.TipoNominativo == "PROP" && soggetto.Principale.GetValueOrDefault())) { itemRiporto = cloneItem(kvp.Value); itemRiporto.DescrizioneConto = "Saldo Esercizio Precedente"; itemRiporto.OrdineConto = 9991; itemRiporto.CodiceConto = null; itemRiporto.DisabilitaStampaMillesimi = true; if (accorpamentoUnita) { var propPrincipale = (from item in soggettiAttivi[kvp.Value.IdUnitaImmobiliare] where item.Tipo == TipoSoggetto.Proprietario && item.Principale.GetValueOrDefault() orderby item.DataInizio.GetValueOrDefault() descending select item).FirstOrDefault(); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (from item in soggetto.UnitaImmobiliare.Proprietari where item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura orderby item.DataInizio.GetValueOrDefault() descending select item).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio.ToString()); } itemRiporto.IdPartecipante = propPrincipale.ID; itemRiporto.IdPersona = propPrincipale.Persona.ID; itemRiporto.Nominativo = propPrincipale.UnitaImmobiliare.Descrizione; } itemRiporto.Importo = saldo != null ? saldo.Value : 0; var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemRiporto.IdPartecipante, false); itemRiporto.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemRiporto.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); lista.Add(kvp.Key + "_RIPORTO", itemRiporto); saldiCalcolati.Add(kvp.Value.IdPartecipante, itemRiporto); } } // --------------------------------------------------------- // Versamenti // --------------------------------------------------------- var itemVersato = new ReportRipartizioneBilancioDTO(); if (!versamentiCalcolati.Contains(kvp.Value.IdPartecipante)) { decimal versamento; if (!accorpamentoUnita) { var kvp1 = kvp; versamento = (versamenti.Where(item => item.Id == kvp1.Value.IdPartecipante)).Sum(item => item.Importo); } else { var kvp1 = kvp; var soggettiUnita = soggettiAttivi[kvp1.Value.IdUnitaImmobiliare].Select(item => item.ID); versamento = (versamenti.Where(item => soggettiUnita.Contains(item.Id))).Sum(item => item.Importo); } // Inserisco il versamento solo se diverso da 0, oppure se è relativo al proprietario. (bugid#999) // La riga del proprietario deve essere sempre presente anche se tutti gli importi sono a 0, il conduttore // invece non deve essere presente se gli importi sono a 0 if (versamento != 0 || (kvp.Value.TipoNominativo == "PROP" && soggetto != null && soggetto.Principale.GetValueOrDefault())) { itemVersato = cloneItem(kvp.Value); itemVersato.DescrizioneConto = "Versato"; itemVersato.OrdineConto = 9992; itemVersato.CodiceConto = null; itemVersato.DisabilitaStampaMillesimi = true; if (accorpamentoUnita) { var propPrincipale = findProprietarioPrincipale(kvp.Value.IdUnitaImmobiliare, soggettiAttivi, soggetto.UnitaImmobiliare, esercizio); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (soggetto.UnitaImmobiliare.Proprietari.Where( item => item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio.ToString()); } itemVersato.IdPartecipante = propPrincipale.ID; itemVersato.IdPersona = propPrincipale.Persona.ID; itemVersato.Nominativo = propPrincipale.UnitaImmobiliare.Descrizione; } var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemVersato.IdPartecipante, false); itemVersato.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemVersato.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); itemVersato.Importo = versamento; lista.Add(kvp.Key + "_VERSATO", itemVersato); versamentiCalcolati.Add(kvp.Value.IdPartecipante); } } //---------------------------------------------------------- // Versamenti dopo la chiusura //---------------------------------------------------------- if (pianoRatealeDettaglio != null && pianoRatealeDettaglio.RateSoggetti.Count > 0 && !partecipantiElaborati.Contains(kvp.Value.IdPartecipante)) { var kvp1 = kvp; partecipantiElaborati.Add(kvp.Value.IdPartecipante); var itemVersamentoDopoChiusura = cloneItem(kvp.Value); itemVersamentoDopoChiusura.DescrizioneConto = "Di cui Versamenti dopo la Chiusura"; itemVersamentoDopoChiusura.OrdineConto = 9995; itemVersamentoDopoChiusura.CodiceConto = null; itemVersamentoDopoChiusura.DisabilitaStampaMillesimi = true; if (accorpamentoUnita) { var propPrincipale = findProprietarioPrincipale(kvp.Value.IdUnitaImmobiliare, soggettiAttivi, soggetto.UnitaImmobiliare, esercizio); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (soggetto.UnitaImmobiliare.Proprietari.Where( item => item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); _log.WarnFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio); } itemVersamentoDopoChiusura.IdPartecipante = propPrincipale.ID; itemVersamentoDopoChiusura.IdPersona = propPrincipale.Persona.ID; itemVersamentoDopoChiusura.Nominativo = propPrincipale.UnitaImmobiliare.Descrizione; } var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemVersamentoDopoChiusura.IdPartecipante, false); itemVersamentoDopoChiusura.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemVersamentoDopoChiusura.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); itemVersamentoDopoChiusura.Importo = pianoRatealeDettaglio.RateSoggetti.Where(item => item.Soggetto.ID == kvp1.Value.IdPartecipante).Sum(item => item.Importo); lista.Add(kvp.Key + "_VERSATODOPOCHIUSURA", itemVersamentoDopoChiusura); } // --------------------------------------------------------- // Importi a Debito e a Credito // --------------------------------------------------------- var importoTotale = kvp.Value.Importo.Value + itemRiporto.Importo.GetValueOrDefault() - itemVersato.Importo.GetValueOrDefault(); // Solo se l'importo è <> 0 oppure se la riga è relativa al proprietario principale if (importoTotale != 0 || (kvp.Value.TipoNominativo == "PROP" && soggetto != null && soggetto.Principale.GetValueOrDefault())) { var idSoggettoTotali = kvp.Value.IdPartecipante; if (accorpamentoUnita) { var propPrincipale = findProprietarioPrincipale(kvp.Value.IdUnitaImmobiliare, soggettiAttivi, soggetto.UnitaImmobiliare, esercizio); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (soggetto.UnitaImmobiliare.Proprietari.Where( item => item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio.ToString()); } idSoggettoTotali = propPrincipale.ID; } var importoDto = totaliCalcolati.SingleOrDefault(item => item.IdPartecipante == idSoggettoTotali); if (importoDto == null) { importoDto = cloneItem(kvp.Value); importoDto.Importo = importoTotale; totaliCalcolati.Add(importoDto); } else importoDto.Importo += importoTotale; } // se necessario inverto i saldi if (impostazioni != null && impostazioni.InversioneSaldiRate) itemRiporto.Importo = itemRiporto.Importo.GetValueOrDefault() * -1; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SALDI E VERSAMENTI - {0} - unità:{1} - soggetto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), kvp.Value.IdUnitaImmobiliare, kvp.Value.IdPartecipante, idEsercizio); throw; } } // =================================================================== // Rielaboro i totali calcolati // =================================================================== foreach (var itemTotale in totaliCalcolati) { var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemTotale.IdPartecipante, false); // Debito var itemDebitoCredito = cloneItem(itemTotale); itemDebitoCredito.CodiceConto = null; itemDebitoCredito.Importo = itemTotale.Importo; itemDebitoCredito.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemDebitoCredito.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); if (itemTotale.Importo > 0) { itemDebitoCredito.DescrizioneConto = "a Debito"; itemDebitoCredito.OrdineConto = 9993; } else { itemDebitoCredito.DescrizioneConto = "a Credito"; itemDebitoCredito.OrdineConto = 9994; } if (inversioneSaldi) itemDebitoCredito.Importo = itemDebitoCredito.Importo * -1; lista.Add(itemDebitoCredito.IdPartecipante + "_DEBITOCREDITO", itemDebitoCredito); } } else { //============================================================================================================== // Stampa detrazioni devo rielaborare i totali //============================================================================================================== foreach (var kvp in totali) { try { lista.Add(kvp.Key, kvp.Value); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - TOTALI IN STAMPA DETRAZIONI - {0} - unità:{1} - soggetto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), kvp.Value.IdUnitaImmobiliare, kvp.Value.IdPartecipante, idEsercizio); throw; } } } //============================================================================================================== // Rielaboro lista finale //============================================================================================================== IList<ReportRipartizioneBilancioDTO> listaRiparto; try { // Tolgo gli elementi FAKE aggiunti per permettere l'inserimento di tutti i saldi e versamenti listaRiparto = lista.Values.Where(item => item.CodiceConto != "666").ToList(); // I Millesimi deve comparire solo sul primo soggetto per una stessa unità immmobiliare (bugid#1002) var listaContoGroup = listaRiparto.GroupBy(item => item.IdConto).Select(contoGroup => contoGroup); foreach (var itemGroup in listaContoGroup) { var listaUnitaGroup = itemGroup.GroupBy(item => item.IdUnitaImmobiliare).Select(unitaGroup => unitaGroup); foreach (var unitaGroup in listaUnitaGroup) { var first = true; foreach (var item in unitaGroup.OrderByDescending(item2 => item2.TipoNominativo).ThenBy(item2 => item2.Nominativo)) { if (!first) item.Millesimi = null; first = false; } } } //============================================================================================================== // Applico eventuali accorpamenti //============================================================================================================== if (!accorpamentoUnita) { var soggetti = new List<SoggettoCondominio>(); foreach (var kvp in soggettiAttivi) soggetti.AddRange(kvp.Value.ToList()); listaRiparto = elaboraAccorpamento(listaRiparto, tipoAccorpamento, soggetti, millesimiAttivi, esercizio, null, null); } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - RIELABORAZIONE LISTA FINALE - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio); throw; } //============================================================================================================== // Elimino righe per conti vuoti //============================================================================================================== listaRiparto = elaboraRigheContiVuoti(listaRiparto); //============================================================================================================== // Aggiungo colonna spese conduzione //============================================================================================================== var listaConduzione = listaRiparto.Where(item => item.OrdineConto < 9990 && item.TipoNominativo == "COND").GroupBy(item => item.IdPartecipante).ToList(); foreach (var item in listaConduzione) { var firstItem = item.FirstOrDefault(); if (firstItem != null) { // Debito var itemConduzione = cloneItem(firstItem); itemConduzione.IdConto = 0; itemConduzione.CodiceConto = null; itemConduzione.IdSottoConto = null; itemConduzione.CodiceSottoConto = null; itemConduzione.Importo = item.Sum(itemImporto => itemImporto.Importo); itemConduzione.TipoNominativo = "COND"; itemConduzione.TipoNominativoEffettivo = firstItem.TipoNominativoEffettivo; itemConduzione.DescrizioneConto = "Spese Conduzione"; itemConduzione.OrdineConto = 9996; listaRiparto.Add(itemConduzione); lista.Add(itemConduzione.IdPartecipante + "_CONDUZIONE", itemConduzione); } } //============================================================================================================== // ARROTONDAMENTO Importi generazione di una nuova riga di arrotondamenti //============================================================================================================== var importiNonArrotondati = new List<ReportRipartizioneBilancioDTO>(); foreach (var reportRipartizioneBilancioDTO in listaRiparto.Where(item => item.OrdineConto < 9990)) { if (reportRipartizioneBilancioDTO.Importo != null) { var importoArrotondato = Math.Round(reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(), 2); var importoArrotondamento = reportRipartizioneBilancioDTO.Importo.GetValueOrDefault() - importoArrotondato; var itemImportoArrotondato = importiNonArrotondati.FirstOrDefault(item => item.IdConto == reportRipartizioneBilancioDTO.IdConto && item.DescrizioneConto == reportRipartizioneBilancioDTO.DescrizioneConto); if (itemImportoArrotondato == null) { itemImportoArrotondato = getItemArrotondamenti(reportRipartizioneBilancioDTO); itemImportoArrotondato.Importo = importoArrotondamento; importiNonArrotondati.Add(itemImportoArrotondato); } else itemImportoArrotondato.Importo += importoArrotondamento; reportRipartizioneBilancioDTO.Importo = importoArrotondato; } } // Aggiungo anche il totale degli arrotondamenti var totaleArrotondamento = 0m; foreach (var reportRipartizioneBilancioDTO in importiNonArrotondati) { reportRipartizioneBilancioDTO.Importo = Math.Round(reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(), 2); totaleArrotondamento += reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(); } if (totaleArrotondamento != 0) { var itemImportoArrotondato = getItemArrotondamenti(importiNonArrotondati.FirstOrDefault()); itemImportoArrotondato.OrdineConto = 9990; itemImportoArrotondato.IdConto = 0; itemImportoArrotondato.DescrizioneConto = "Totale Spese"; itemImportoArrotondato.IdSottoConto = null; itemImportoArrotondato.Importo = totaleArrotondamento; importiNonArrotondati.Add(itemImportoArrotondato); var itemImportoArrotondatoDebitoCredito = getItemArrotondamenti(importiNonArrotondati.FirstOrDefault()); itemImportoArrotondatoDebitoCredito.IdConto = 0; itemImportoArrotondatoDebitoCredito.IdSottoConto = null; itemImportoArrotondatoDebitoCredito.Importo = totaleArrotondamento; if (inversioneSaldi) itemImportoArrotondatoDebitoCredito.Importo = itemImportoArrotondatoDebitoCredito.Importo * -1; if (totaleArrotondamento < 0) { itemImportoArrotondatoDebitoCredito.OrdineConto = 9994; itemImportoArrotondatoDebitoCredito.DescrizioneConto = "a Credito"; } else { itemImportoArrotondatoDebitoCredito.OrdineConto = 9993; itemImportoArrotondatoDebitoCredito.DescrizioneConto = "a Debito"; } importiNonArrotondati.Add(itemImportoArrotondatoDebitoCredito); } foreach (var reportRipartizioneBilancioDTO in importiNonArrotondati) { listaRiparto.Add(reportRipartizioneBilancioDTO); } // ====================================================== // Add Empty items - Per una corretta visualizzazione // nel report multicolonna // ====================================================== if (!ripartizioneProprietarioConduttore && !dettaglioSottoConto) { var emptyItems = getEmptyItems(listaRiparto); foreach (var reportRipartizioneBilancioDTO in emptyItems) listaRiparto.Add(reportRipartizioneBilancioDTO); } // ====================================================== // Rielaborazione millesimi // ====================================================== elaborazioneMillesimi(listaRiparto); // ====================================================== // Rielaborazione nominativi // ====================================================== elaborazioneNominativi(listaRiparto); // ====================================================== // Ritorno solo le righe dei condomini selezionati // ====================================================== if (idSoggetti != null) listaRiparto = listaRiparto.Where(item => (item.OrdineConto < 9990 || item.OrdineConto == 9991 || item.OrdineConto == 9992) && idSoggetti.Contains(item.IdPartecipante)).ToList(); return listaRiparto.OrderBy(item => item.IdGruppoStabile); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - {0} - esercizio:{1} - condominio:{2} - anno:{3} - detrazione:{4} - stabile:{5} - scala:{6} - ripartizioneProprietarioConduttore:{7} - accorpamentoUnita:{8} - inversioneSaldi:{9}", ex, Utility.GetMethodDescription(), idEsercizio, idCondominio.GetValueOrDefault(), anno.GetValueOrDefault(), detrazione.GetValueOrDefault(), idStabile.GetValueOrDefault(), idScala.GetValueOrDefault(), ripartizioneProprietarioConduttore, tipoAccorpamento, inversioneSaldi); throw; } }
private ReportRipartizioneBilancioDTO getItemTotale(ReportRipartizioneBilancioDTO item) { var itemTotale = cloneItem(item); itemTotale.IdConto = 0; itemTotale.Importo = 0; itemTotale.DescrizioneConto = "Totale Spese"; itemTotale.OrdineConto = 9990; itemTotale.DisabilitaStampaMillesimi = true; return itemTotale; }
private List<ReportRipartizioneBilancioDTO> elaboraSoggetto(SoggettoCondominio soggetto, IEnumerable<SoggettoCondominio> soggettiAttivi, IList<ReportRipartizioneBilancioDTO> totali, Esercizio esercizio, bool accorpamentoUnita) { try { if (totali.All(item => item.IdPartecipante != soggetto.ID)) { var fakeItem = new ReportRipartizioneBilancioDTO { IdPartecipante = soggetto.ID, IdPersona = soggetto.Persona.ID, IdUnitaImmobiliare = soggetto.UnitaImmobiliare.ID, TipoUnitaImmobiliare = soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione, Nominativo = soggetto.DisplayName, OrdineUnitaImmobiliare = soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault(), SubalternoUnitaImmobiliare = soggetto.UnitaImmobiliare.Subalterno, PianoUnitaImmobiliare = soggetto.UnitaImmobiliare.Piano, InternoUnitaImmobiliare = getInternoUnitaImmobiliare(soggetto.UnitaImmobiliare), OrdineStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.Ordine, OrdineGruppoStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.Ordine, DescrizioneStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.Descrizione, DescrizioneGruppoStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.Descrizione, IdStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.ID, IdGruppoStabile = soggetto.UnitaImmobiliare.GruppoStabileRiferimento.ID, TipoNominativo = (soggetto.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND", TipoNominativoEffettivo = soggetto.Tipo.ToString().Substring(0, 1), CodiceConto = "666", DisabilitaStampaMillesimi = true, Importo = 0, DataUscitaPartecipante = getDataUscita(soggetto), OrdinePartecipante = soggetto.Tipo == TipoSoggetto.Proprietario ? 10 : 20 }; if (accorpamentoUnita) { var propPrincipale = (from item in soggettiAttivi where item.Tipo == TipoSoggetto.Proprietario && item.Principale.GetValueOrDefault() && item.UnitaImmobiliare.ID == soggetto.UnitaImmobiliare.ID select item).SingleOrDefault(); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (from item in soggetto.UnitaImmobiliare.Proprietari where item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura orderby item.DataInizio.GetValueOrDefault() descending select item).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, esercizio.ID); } if (propPrincipale != null) { fakeItem.IdPartecipante = propPrincipale.ID; fakeItem.IdPersona = propPrincipale.Persona.ID; } fakeItem.Nominativo = soggetto.UnitaImmobiliare.Descrizione; } totali.Add(fakeItem); } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - FAKE - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), esercizio.ID); throw; } return totali.ToList(); }
private IList<ReportRipartizioneBilancioDTO> getReportItemsPreventivo(Esercizio esercizio, RendicontoAnnuale rendicontoDaUsare, IList<SoggettoCondominio> soggettiAttivi, int? idStabile, int? idScala, bool ripartizioneProprietarioConduttore, bool accorpamentoUnita, bool inversioneSaldi, bool calcoloPerSubentro, bool addebitiCondominio, bool addebitiDirettiStabileScala, bool dettaglioSottoConto) { var condominio = esercizio.CondominioRiferimento; var idEsercizio = esercizio.ID; var lista = new Dictionary<string, ReportRipartizioneBilancioDTO>(); // ============================================================================================= // Se esiste devo proporre lo storico // ============================================================================================= var listaStorico = getStoricoRiparto(idEsercizio, idStabile, idScala, addebitiDirettiStabileScala, TipoRendiconto.Preventivo); if (listaStorico.Any()) { return listaStorico.Where(item => item.IdConto > 0).ToList(); } else { // ============================================================================================= // Ricalcolo i saldi solo se ho un esercizio precedente aperto // ============================================================================================= var esercizioPrecedente = esercizio.GetEsercizioPrecedente(); if (esercizioPrecedente != null && esercizioPrecedente.Stato == StatoEsercizioEnum.Aperto) _saldoContabileService.TrasferimentoSaldiNuovoEsercizio(esercizio.ID, this, calcoloPerSubentro); //==================================================================================== // Raggruppo gli importi del preventivo per Conto, Sottoconto, Lotto, Stabile e Scala //==================================================================================== IList<ReportRipartizioneBilancioDTO> consuntivo = null; if (rendicontoDaUsare.Conti.Any(item => item.GetConto().IsRipartoLetture)) { // Il calcolo dal consuntivo, necessario per ripartire il preventivo se presente un conto a letture, deve sempre essere calcolato senza accorpamenti // bugid#4171 if (esercizioPrecedente != null) consuntivo = GetDataSourceRipartizioneBilancioConsuntivo(esercizioPrecedente.ID, null, null, null, null, idStabile, idScala, ripartizioneProprietarioConduttore, accorpamentoUnita, TipoAccorpamentoRateEnum.Nessuno, inversioneSaldi, calcoloPerSubentro, addebitiCondominio, addebitiDirettiStabileScala, null).ToList(); } var importiConto = new List<ImportiContoSottocontoDTO>(); foreach (var rendicontoAnnualeConto in rendicontoDaUsare.Conti.Where(item => !item.GetConto().IsSpesePersonali)) { if (!addebitiCondominio || !addebitiDirettiStabileScala || (rendicontoAnnualeConto.Stabile == null && rendicontoAnnualeConto.GruppoStabile == null)) { if (!addebitiDirettiStabileScala || ( (idStabile == null || (rendicontoAnnualeConto.Stabile != null && rendicontoAnnualeConto.Stabile.ID == idStabile.GetValueOrDefault())) && (idScala == null || (rendicontoAnnualeConto.GruppoStabile != null && rendicontoAnnualeConto.GruppoStabile.ID == idScala.GetValueOrDefault())) )) { int? idSottoConto = null; if (dettaglioSottoConto) { if (rendicontoAnnualeConto.SottoContoRiferimento != null) idSottoConto = rendicontoAnnualeConto.SottoContoRiferimento.ID; else idSottoConto = rendicontoAnnualeConto.GetConto().ID *-1; } int? idStabileConto = null; if (rendicontoAnnualeConto.Stabile != null) idStabileConto = rendicontoAnnualeConto.Stabile.ID; int? idScalaConto = null; if (rendicontoAnnualeConto.GruppoStabile != null) idScalaConto = rendicontoAnnualeConto.GruppoStabile.ID; var importoConto = new ImportiContoSottocontoDTO { Conto = rendicontoAnnualeConto.GetConto().ID, SottoConto = idSottoConto, Stabile = idStabileConto, Scala = idScalaConto, ImportoProprieta = _ripartizioneService.GetImportoCompetenza( rendicontoAnnualeConto.Importo.GetValueOrDefault(), rendicontoAnnualeConto.GetConto(), rendicontoAnnualeConto.SottoContoRiferimento, TipoSoggetto.Proprietario), ImportoConduzione = _ripartizioneService.GetImportoCompetenza( rendicontoAnnualeConto.Importo.GetValueOrDefault(), rendicontoAnnualeConto.GetConto(), rendicontoAnnualeConto.SottoContoRiferimento, TipoSoggetto.Conduttore) }; addImporto(importoConto, importiConto); } } } //==================================================================================== // Eseguo il riparto //==================================================================================== var millesimi = _daoFactory.GetMillesimoDao().GetByCondominio(condominio.ID); var millesimiGroupByConto = millesimi.GroupBy(item => item.ContoRiferimento.ID).ToList(); var unitaImmobiliari = _daoFactory.GetUnitaImmobiliareDao().GetByCondominio(condominio.ID).ToDictionary(item => item.ID); var conti = _daoFactory.GetContoDao().GetByCondominio(condominio.ID).ToDictionary(item => item.ID); var soggetti = soggettiAttivi.ToDictionary(item => item.ID); var riparto = new List<SpeseUnitaRipartoDTO>(); foreach (var importiContoSottocontoDTO in importiConto) riparto.AddRange(getRiparto(importiContoSottocontoDTO, millesimiGroupByConto, consuntivo, esercizio, dettaglioSottoConto)); // ------------------------------------------------------------------ // Proprietari attivi // ------------------------------------------------------------------ var listaProprietariAttivi = new Dictionary<int, IList<SoggettoCondominio>>(); var proprietariSoggettiAttivi = new Dictionary<int, SoggettoCondominio>(); foreach (var soggettoCondominio in soggettiAttivi.Where(item => item.Tipo == TipoSoggetto.Proprietario)) { if (soggettoCondominio.Principale.GetValueOrDefault()) { if (proprietariSoggettiAttivi.ContainsKey(soggettoCondominio.UnitaImmobiliare.ID)) { if (soggettoCondominio.DataInizio.GetValueOrDefault() > proprietariSoggettiAttivi[soggettoCondominio.UnitaImmobiliare.ID].DataInizio.GetValueOrDefault() || proprietariSoggettiAttivi[soggettoCondominio.UnitaImmobiliare.ID].DataFine != null) proprietariSoggettiAttivi[soggettoCondominio.UnitaImmobiliare.ID] = soggettoCondominio; } else proprietariSoggettiAttivi.Add(soggettoCondominio.UnitaImmobiliare.ID, soggettoCondominio); } if (listaProprietariAttivi.ContainsKey(soggettoCondominio.UnitaImmobiliare.ID)) listaProprietariAttivi[soggettoCondominio.UnitaImmobiliare.ID].Add(soggettoCondominio); else listaProprietariAttivi.Add(soggettoCondominio.UnitaImmobiliare.ID, new List<SoggettoCondominio> { soggettoCondominio }); } // ------------------------------------------------------------------ // Conduttori attivi // ------------------------------------------------------------------ var conduttoriSoggettiAttivi = new Dictionary<int, IList<SoggettoCondominio>>(); foreach (var soggettoCondominioUnita in soggettiAttivi.Where(item => item.Tipo == TipoSoggetto.Conduttore).GroupBy(item => item.UnitaImmobiliare)) conduttoriSoggettiAttivi.Add(soggettoCondominioUnita.Key.ID, soggettoCondominioUnita.ToList()); var soggettiAttiviByUnitaImmobiliare = new Dictionary<int, IList<SoggettoCondominio>>(); foreach (var soggettoCondominioUnita in soggettiAttivi.GroupBy(item => item.UnitaImmobiliare)) soggettiAttiviByUnitaImmobiliare.Add(soggettoCondominioUnita.Key.ID, soggettoCondominioUnita.ToList()); // ------------------------------------------------------------------ // Aggiungo le spese personali (NON sono soggette a riparto) // ------------------------------------------------------------------ foreach (var rendicontoAnnualeConto in rendicontoDaUsare.Conti.Where(item => item.GetConto().IsSpesePersonali)) { riparto.AddRange(rendicontoAnnualeConto.DettagliUnita.Select(spesa => new SpeseUnitaRipartoDTO { ID = spesa.ID, IdConto = rendicontoAnnualeConto.GetConto().ID, IdUnita = spesa.Unita.ID, UnitaMisuraMillesimo = "PC", ImportoConduttore = _ripartizioneService.GetImportoCompetenza(spesa.Importo.GetValueOrDefault(), rendicontoAnnualeConto.GetConto(), rendicontoAnnualeConto.SottoContoRiferimento, TipoSoggetto.Conduttore), ImportoProprietario = _ripartizioneService.GetImportoCompetenza(spesa.Importo.GetValueOrDefault(), rendicontoAnnualeConto.GetConto(), rendicontoAnnualeConto.SottoContoRiferimento, TipoSoggetto.Proprietario) })); } //===================================================================================================== // Elaborazione delle ripartizioni //===================================================================================================== var index = 0; foreach (var spesa in riparto) { try { index++; var conto = conti.ContainsKey(spesa.IdConto) ? conti[spesa.IdConto] : _daoFactory.GetContoDao().GetById(spesa.IdConto, false); var unita = unitaImmobiliari.ContainsKey(spesa.IdUnita.GetValueOrDefault()) ? unitaImmobiliari[spesa.IdUnita.GetValueOrDefault()] : _daoFactory.GetUnitaImmobiliareDao().GetById(spesa.IdUnita.GetValueOrDefault(), false); SottoConto sottoconto = null; if (spesa.IdSottoConto > 0) sottoconto = conto.SottoConti.FirstOrDefault(item => item.ID == spesa.IdSottoConto.Value); // ------------------------------------------------------- // Verifica se appartiene a scala e/o stabile selezionato // ------------------------------------------------------- if (idStabile != null) { if (unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID != idStabile.Value) continue; } if (idScala != null) { if (unita.GruppoStabileRiferimento.ID != idScala.Value) continue; } // ------------------------- // Proprietario // ------------------------- SoggettoCondominio proprietarioPrincipale = null; if(proprietariSoggettiAttivi.ContainsKey(spesa.IdUnita.GetValueOrDefault())) proprietarioPrincipale = proprietariSoggettiAttivi[spesa.IdUnita.GetValueOrDefault()]; // 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 < esercizio.DataChiusura orderby item.DataInizio.GetValueOrDefault() descending select item).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), spesa.IdUnita, idEsercizio.ToString()); } var importoProprieta = spesa.ImportoProprietario; if (importoProprieta != 0) { var soggProp = new List<ImportiDTO>(); if (!accorpamentoUnita) { var soggPropRip = (conto.SoggettiRipartizione.Where(itemSogg => itemSogg.PercentualeRipartizione > 0 && itemSogg.Soggetto.Tipo == TipoSoggetto.Proprietario && itemSogg.Soggetto.UnitaImmobiliare.ID == spesa.IdUnita)).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.GetValueOrDefault() * sogg.PercentualeRipartizione) / totaleSoggPropRip }); } else if (soggPropRip.Count == 0) { IList<SoggettoCondominio> proprietariAttivi = new List<SoggettoCondominio>(); if(listaProprietariAttivi.ContainsKey(spesa.IdUnita.GetValueOrDefault())) proprietariAttivi = listaProprietariAttivi[spesa.IdUnita.GetValueOrDefault()]; if (proprietariAttivi.Count == 0 && proprietarioPrincipale != null) proprietariAttivi.Add(proprietarioPrincipale); soggProp.AddRange(proprietariAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (importoProprieta.GetValueOrDefault() * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 })); } } else soggProp.Add(new ImportiDTO(proprietarioPrincipale.ID, importoProprieta.GetValueOrDefault())); foreach (var idSogg in soggProp) { try { if (idSogg.Importo != 0) { var key = spesa.IdConto + "_" + spesa.IdUnita; if (!accorpamentoUnita) key += "_" + idSogg.Id; key += "_PROP"; ReportRipartizioneBilancioDTO item; if (lista.ContainsKey(key)) item = lista[key]; else { item = new ReportRipartizioneBilancioDTO(); lista.Add(key, item); item.IdPartecipante = idSogg.Id; item.Importo = 0; item.IdConto = spesa.IdConto; item.IdUnitaImmobiliare = spesa.IdUnita.GetValueOrDefault(); item.IdStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID; item.IdGruppoStabile = unita.GruppoStabileRiferimento.ID; item.DisabilitaStampaMillesimi = conto.IsSpesePersonali || conto.DisabilitaMillesimiRiparto; var codice = string.Empty; if (conto.Codice != null) codice = conto.Codice; item.CodiceConto = codice; item.DescrizioneConto = !string.IsNullOrEmpty(conto.DescrizioneBilancio) && !dettaglioSottoConto ? conto.DescrizioneBilancio : conto.Descrizione; if (dettaglioSottoConto) { var codiceSottoConto = string.Empty; var descrizioneSottoConto = string.Empty; if (sottoconto != null) { if (!string.IsNullOrEmpty(sottoconto.Codice)) codiceSottoConto = sottoconto.Codice; descrizioneSottoConto = sottoconto.Descrizione; } else if (spesa.IdSottoConto < 0) { descrizioneSottoConto = item.DescrizioneConto; codiceSottoConto = item.CodiceConto; } item.CodiceSottoConto = codiceSottoConto; item.DescrizioneSottoConto = descrizioneSottoConto; item.IdSottoConto = spesa.IdSottoConto; } item.OrdineConto = conto.Ordine; item.TipoUnitaImmobiliare = unita.TipoUnitaImmobiliare.Descrizione; item.DescrizioneGruppoStabile = unita.GruppoStabileRiferimento.Descrizione; item.OrdineGruppoStabile = unita.GruppoStabileRiferimento.Ordine; item.DescrizioneStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Descrizione; item.OrdineStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Ordine; item.OrdineUnitaImmobiliare = unita.Ordine.GetValueOrDefault(); item.SubalternoUnitaImmobiliare = unita.Subalterno; item.PianoUnitaImmobiliare = unita.Piano; item.InternoUnitaImmobiliare = getInternoUnitaImmobiliare(unita); item.Millesimi = spesa.ValoreMillesimo; item.UnitaMisuraMillesimi = spesa.UnitaMisuraMillesimo; if (!accorpamentoUnita) { var sogg = findSoggettoCondominio(idSogg.Id, soggetti); item.DataUscitaPartecipante = getDataUscita(sogg); item.Nominativo = sogg.DisplayName; item.IdPersona = sogg.Persona.ID; } else { item.DataUscitaPartecipante = getDataUscita(proprietarioPrincipale); item.Nominativo = proprietarioPrincipale.UnitaImmobiliare.Descrizione; item.IdPartecipante = proprietarioPrincipale.ID; item.IdPersona = proprietarioPrincipale.Persona.ID; } item.OrdinePartecipante = 10; item.TipoNominativo = "PROP"; item.TipoNominativoEffettivo = findSoggettoCondominio(item.IdPartecipante, soggetti).Tipo.ToString().Substring(0, 1); item.NumeroColonne = 1; item.IdGruppoStabileAddebito = spesa.IdGruppoStabileAddebito; item.IdStabileAddebito = spesa.IdStabileAddebito; } item.Importo += idSogg.Importo; } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SPESE PROPRIETARI - {0} - soggetto:{1} - spesa:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), idSogg.Id, spesa.ID, idEsercizio); throw; } } } // ------------------------- // Conduttore // ------------------------- if (spesa.ImportoConduttore != 0) { var soggCond = new List<ImportiDTO>(); if (!accorpamentoUnita) { var soggCondRip = (conto.SoggettiRipartizione.Where( itemSogg => itemSogg.PercentualeRipartizione > 0 && itemSogg.Soggetto.Tipo == TipoSoggetto.Conduttore && itemSogg.Soggetto.UnitaImmobiliare.ID == spesa.IdUnita)).ToList(); if (soggCondRip.Count > 0) { var totaleSoggCondRip = soggCondRip.Sum(item => item.PercentualeRipartizione); soggCond.AddRange(soggCondRip.Select(sogg => new ImportiDTO { Id = sogg.Soggetto.ID, Importo = (spesa.ImportoConduttore.GetValueOrDefault() * sogg.PercentualeRipartizione) / totaleSoggCondRip })); } else if (soggCondRip.Count == 0) { var conduttoriAttivi = new List<SoggettoCondominio>(); if(conduttoriSoggettiAttivi.ContainsKey(spesa.IdUnita.GetValueOrDefault())) conduttoriAttivi = conduttoriSoggettiAttivi[spesa.IdUnita.GetValueOrDefault()].Where(item => item.PercentualeRiferimento > 0).ToList(); if (!conduttoriAttivi.Any()) { if(listaProprietariAttivi.ContainsKey(spesa.IdUnita.GetValueOrDefault())) conduttoriAttivi.AddRange(listaProprietariAttivi[spesa.IdUnita.GetValueOrDefault()]); } soggCond.AddRange(conduttoriAttivi.Select(soggAttivo => new ImportiDTO { Id = soggAttivo.ID, Importo = (spesa.ImportoConduttore.GetValueOrDefault() * soggAttivo.PercentualeRiferimento.GetValueOrDefault()) / 100 })); } } else if (proprietarioPrincipale != null) soggCond.Add(new ImportiDTO(proprietarioPrincipale.ID, spesa.ImportoConduttore.GetValueOrDefault())); else { _log.ErrorFormat("Unità immobiliare senza proprietario principale - {0} - idUnita:{1}", Utility.GetMethodDescription(), unita.ID); throw new InvalidDataException($"L'unità immobiliare {unita.Descrizione} non ha un proprietario principale"); } foreach (var idSogg in soggCond) { try { if (idSogg.Importo != 0) { var key = spesa.IdConto + "_" + spesa.IdUnita; if (!accorpamentoUnita) key += "_" + idSogg.Id; key += "_COND"; ReportRipartizioneBilancioDTO item; if (lista.ContainsKey(key)) item = lista[key]; else { item = new ReportRipartizioneBilancioDTO(); lista.Add(key, item); item.IdPartecipante = idSogg.Id; item.Importo = 0; item.IdConto = spesa.IdConto; item.IdStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.ID; item.IdGruppoStabile = unita.GruppoStabileRiferimento.ID; item.IdUnitaImmobiliare = spesa.IdUnita.GetValueOrDefault(); item.DisabilitaStampaMillesimi = conto.IsSpesePersonali || conto.DisabilitaMillesimiRiparto; var codice = string.Empty; if (conto.Codice != null) codice = conto.Codice; item.CodiceConto = codice; item.DescrizioneConto = !string.IsNullOrEmpty(conto.DescrizioneBilancio) && !dettaglioSottoConto ? conto.DescrizioneBilancio : conto.Descrizione; item.OrdineConto = conto.Ordine; if (dettaglioSottoConto) { var codiceSottoConto = string.Empty; var descrizioneSottoConto = string.Empty; if (sottoconto != null) { if (!string.IsNullOrEmpty(sottoconto.Codice)) codiceSottoConto = sottoconto.Codice; descrizioneSottoConto = sottoconto.Descrizione; } else if (spesa.IdSottoConto < 0) { descrizioneSottoConto = item.DescrizioneConto; codiceSottoConto = item.CodiceConto; } item.CodiceSottoConto = codiceSottoConto; item.DescrizioneSottoConto = descrizioneSottoConto; item.IdSottoConto = spesa.IdSottoConto; } item.TipoUnitaImmobiliare = unita.TipoUnitaImmobiliare.Descrizione; item.DescrizioneGruppoStabile = unita.GruppoStabileRiferimento.Descrizione; item.DescrizioneStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Descrizione; item.OrdineGruppoStabile = unita.GruppoStabileRiferimento.Ordine; item.OrdineStabile = unita.GruppoStabileRiferimento.PalazzinaRiferimento.Ordine; item.OrdineUnitaImmobiliare = unita.Ordine.GetValueOrDefault(); item.SubalternoUnitaImmobiliare = unita.Subalterno; item.PianoUnitaImmobiliare = unita.Piano; item.InternoUnitaImmobiliare = getInternoUnitaImmobiliare(unita); item.Millesimi = spesa.ValoreMillesimo; item.UnitaMisuraMillesimi = spesa.UnitaMisuraMillesimo; if (!accorpamentoUnita) { var sogg = findSoggettoCondominio(idSogg.Id, soggetti); item.DataUscitaPartecipante = getDataUscita(sogg); item.Nominativo = sogg.DisplayName; item.IdPersona = sogg.Persona.ID; } else { item.DataUscitaPartecipante = getDataUscita(proprietarioPrincipale); item.Nominativo = proprietarioPrincipale.UnitaImmobiliare.Descrizione; item.IdPartecipante = proprietarioPrincipale.ID; item.IdPersona = proprietarioPrincipale.Persona.ID; } item.OrdinePartecipante = 20; item.TipoNominativo = "COND"; item.TipoNominativoEffettivo = ripartizioneProprietarioConduttore ? "C" : findSoggettoCondominio(item.IdPartecipante, soggetti).Tipo.ToString().Substring(0, 1); item.NumeroColonne = 1; } item.Importo += idSogg.Importo; } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SPESE CONDUTTORI - {0} - soggetto:{1} - spesa:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), idSogg.Id, spesa.ID, idEsercizio); throw; } } } } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SPESE - {0} - spesa:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), spesa.ID, idEsercizio); throw; } } //============================================================================================================== // Elaborazione SUBENTRI per avere una riga per ogni soggetto //============================================================================================================== elaboraSubentri(esercizio, accorpamentoUnita, lista, soggettiAttiviByUnitaImmobiliare, conti, dettaglioSottoConto); // ====================================================== // Rielaborazione nominativi // ====================================================== elaborazioneNominativi(lista.Values); return lista.Values.ToList(); } }
private void addListaSoggettiAccorpati(Dictionary<SoggettoCondominio, IList<SoggettoCondominio>> listaSoggettiAccorpati, ReportRipartizioneBilancioDTO reportRipartizioneBilancioDTO, SoggettoCondominio soggetto, IList<SoggettoCondominio> soggettiAttivi) { var soggettoKey = listaSoggettiAccorpati.Keys.FirstOrDefault(item => item.ID == reportRipartizioneBilancioDTO.IdPartecipante); if (soggettoKey != null) { var soggettoValue = listaSoggettiAccorpati[soggettoKey].FirstOrDefault(item => item.ID == soggetto.ID); if (soggettoValue == null) listaSoggettiAccorpati[soggettoKey].Add(soggetto); } else { soggettoKey = soggettiAttivi.FirstOrDefault(item => item.ID == reportRipartizioneBilancioDTO.IdPartecipante) ?? _daoFactory.GetSoggettoCondominioDao().Find(reportRipartizioneBilancioDTO.IdPartecipante, false); listaSoggettiAccorpati.Add(soggettoKey, new List<SoggettoCondominio> { soggetto }); } }
public override IEnumerable<ReportRipartizioneBilancioDTO> GetDataSourceRipartizioneBilancioPreventivo(int idEsercizio, int? idStabile, int? idScala, bool ripartizioneProprietarioConduttore, bool accorpamentoUnita, TipoAccorpamentoRateEnum tipoAccorpamento, bool inversioneSaldi, bool stampaSaldi, bool addebitiCondominio, bool calcoloPerSubentro, bool addebitiDirettiStabileScala, IList<int> idSoggetti, bool dettaglioSottoConto = false) { try { var esercizio = _daoFactory.GetEsercizioDao().GetById(idEsercizio, false); var condominio = esercizio.CondominioRiferimento; var rendicontoDaUsare = getRendicontoPreventivoCorrente(idEsercizio); if (rendicontoDaUsare != null) { ImpostazioniAzienda impostazioni = null; IList<SoggettoCondominio> soggettiEsercizio = null; if (condominio != null) { impostazioni = _daoFactory.GetImpostazioniAziendaDao().GetByAzienda(condominio.Azienda.ID); soggettiEsercizio = _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizio(esercizio, null); } // ------------------------------------------------------------------------------------------- // TODO: Da eliminare quando saranno riscritti i subentri - bugid#8425 var soggettiAttivi = new List<SoggettoCondominio>(); if (soggettiEsercizio != null) { foreach (var soggettoCondominio in soggettiEsercizio) { if (soggettoCondominio.Tipo == TipoSoggetto.Proprietario || soggettoCondominio.DataInizio == null || soggettoCondominio.DataInizio.GetValueOrDefault() <= esercizio.DataApertura.GetValueOrDefault()) soggettiAttivi.Add(soggettoCondominio); } } // ------------------------------------------------------------------------------------------- //============================================================================================================== // Lettura elementi report per CONTO //============================================================================================================== var lista = getReportItemsPreventivo(esercizio, rendicontoDaUsare, soggettiAttivi, idStabile, idScala, ripartizioneProprietarioConduttore, accorpamentoUnita, inversioneSaldi, calcoloPerSubentro, addebitiCondominio, addebitiDirettiStabileScala, dettaglioSottoConto); //============================================================================================================== // Calcolo totali spese //============================================================================================================== var totali = new List<ReportRipartizioneBilancioDTO>(); foreach (var itemGroup in lista.GroupBy(item => item.IdPartecipante.ToString(CultureInfo.InvariantCulture).PadLeft(10, '0') + "&" + item.TipoNominativo)) { var itemSpesa = itemGroup.FirstOrDefault(); var itemTotale = getItemTotale(itemSpesa); itemTotale.Importo = itemGroup.Sum(item => Math.Round(item.Importo.GetValueOrDefault(), 2)); totali.Add(itemTotale); } //============================================================================================================== // Ripartizione delle differenze tra Rendiconto e Riparto //============================================================================================================== var saldi = _daoFactory.GetSaldoSoggettoDao().GetByEsercizioStabileScala(esercizio, idStabile, idScala); var saldiCalcolati = new Dictionary<int, ReportRipartizioneBilancioDTO>(); var totaliCalcolati = new List<ReportRipartizioneBilancioDTO>(); // Se il soggetto non è presente nei totali (quindi non ha nessuna spesa addebitata) lo aggiungo con un elemento FAKE (666), che poi // provvederò a cancellare, per permettere l'inserimento degli elementi di saldo e versamenti // ---------------------------------------------------------------------------------------------------------------------------------- // Saldi if (stampaSaldi) { foreach (var saldo in saldi) { try { totali = elaboraSoggetto(saldo.Soggetto, soggettiAttivi, totali, esercizio, accorpamentoUnita); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo (SALDI) - {0} - (FAKE) - saldo:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), saldo.ID, idEsercizio); throw; } } } //============================================================================================================== // Elaborazione dei totali + saldi //============================================================================================================== foreach (var kvp in totali.Where(item => item.IdPartecipante > 0)) { try { var soggetto = (soggettiAttivi.Where(item => item.ID == kvp.IdPartecipante)).SingleOrDefault() ?? _daoFactory.GetSoggettoCondominioDao().GetById(kvp.IdPartecipante, false); // Può capitare in caso di subentro senza trasferimento di saldi e versamenti lista.Add(kvp); // --------------------------------------------------------- // Saldo Anno Precedente // --------------------------------------------------------- var itemRiporto = new ReportRipartizioneBilancioDTO(); if (stampaSaldi && !saldiCalcolati.ContainsKey(kvp.IdPartecipante)) { // Inserisco il saldo solo se diverso da 0, oppure se è relativo al proprietario principale. (bugid#999) // La riga del proprietario deve essere sempre presente anche se tutti gli importi sono a 0, il conduttore // invece non deve essere presente se gli importi sono a 0 int? idPartecipante = kvp.IdPartecipante; int? idUnitaImmobiliare = null; if (accorpamentoUnita) { idPartecipante = null; idUnitaImmobiliare = kvp.IdUnitaImmobiliare; } var saldo = getSaldoBySoggettoUnita(saldi, idPartecipante, idUnitaImmobiliare); if ((saldo != null && saldo != 0) || (kvp.TipoNominativo == "PROP" && soggetto.Principale.GetValueOrDefault())) { itemRiporto = cloneItem(kvp); itemRiporto.DescrizioneConto = "Saldo Anno Prec"; itemRiporto.OrdineConto = 9991; itemRiporto.CodiceConto = null; itemRiporto.DisabilitaStampaMillesimi = true; if (accorpamentoUnita) { var propPrincipale = (soggettiAttivi.Where( item => item.Tipo == TipoSoggetto.Proprietario && item.Principale.GetValueOrDefault() && item.UnitaImmobiliare.ID == kvp.IdUnitaImmobiliare)).SingleOrDefault(); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (soggetto.UnitaImmobiliare.Proprietari.Where(item => item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio.ToString()); } itemRiporto.IdPartecipante = propPrincipale.ID; itemRiporto.IdPersona = propPrincipale.Persona.ID; itemRiporto.Nominativo = propPrincipale.UnitaImmobiliare.Descrizione; } itemRiporto.Importo = saldo ?? 0; var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemRiporto.IdPartecipante, false); itemRiporto.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemRiporto.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); lista.Add(itemRiporto); saldiCalcolati.Add(kvp.IdPartecipante, itemRiporto); } } // --------------------------------------------------------- // Importi a Debito e a Credito // --------------------------------------------------------- var importoTotale = kvp.Importo.Value + itemRiporto.Importo.GetValueOrDefault(); // Solo se l'importo è <> 0 oppure se la riga è relativa al proprietario principale if (importoTotale != 0 || (kvp.TipoNominativo == "PROP" && soggetto != null && soggetto.Principale.GetValueOrDefault())) { var idSoggettoTotali = kvp.IdPartecipante; if (accorpamentoUnita) { var propPrincipale = (from item in soggettiAttivi where item.Tipo == TipoSoggetto.Proprietario && item.Principale.GetValueOrDefault() && item.UnitaImmobiliare.ID == kvp.IdUnitaImmobiliare select item).SingleOrDefault(); // Se il proprietario non è presente lo cerco tra tutti i proprietari if (propPrincipale == null) { propPrincipale = (soggetto.UnitaImmobiliare.Proprietari.Where(item => item.DataInizio == null || item.DataInizio.Value < esercizio.DataChiusura) .OrderByDescending(item => item.DataInizio.GetValueOrDefault())).FirstOrDefault(); _log.DebugFormat("Non trovato proprietario principale - {0} - unità:{1} - esercizio:{2}", Utility.GetMethodDescription(), soggetto.UnitaImmobiliare.ID, idEsercizio.ToString()); } idSoggettoTotali = propPrincipale.ID; } var importoDto = totaliCalcolati.SingleOrDefault(item => item.IdPartecipante == idSoggettoTotali); if (importoDto == null) { importoDto = cloneItem(kvp); importoDto.Importo = importoTotale; totaliCalcolati.Add(importoDto); } else importoDto.Importo += importoTotale; } // se necessario inverto i saldi if (impostazioni != null && impostazioni.InversioneSaldiRate) itemRiporto.Importo = itemRiporto.Importo.GetValueOrDefault() * -1; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del consuntivo - SALDI E VERSAMENTI - {0} - unità immobiliare:{1} - soggetto:{2} - esercizio:{3}", ex, Utility.GetMethodDescription(), kvp.IdUnitaImmobiliare, kvp.IdPartecipante, idEsercizio); throw; } } // =================================================================== // Rielaboro i totali calcolati // =================================================================== if (stampaSaldi) { foreach (var itemTotale in totaliCalcolati) { var sogg = _daoFactory.GetSoggettoCondominioDao().GetById(itemTotale.IdPartecipante, false); // Debito var itemDebitoCredito = cloneItem(itemTotale); itemDebitoCredito.CodiceConto = null; itemDebitoCredito.Importo = itemTotale.Importo; itemDebitoCredito.TipoNominativo = (sogg.Tipo == TipoSoggetto.Proprietario) ? "PROP" : "COND"; itemDebitoCredito.TipoNominativoEffettivo = sogg.Tipo.ToString().Substring(0, 1); if (itemTotale.Importo > 0) { itemDebitoCredito.DescrizioneConto = "a Debito"; itemDebitoCredito.OrdineConto = 9993; } else { itemDebitoCredito.DescrizioneConto = "a Credito"; itemDebitoCredito.OrdineConto = 9994; } if (inversioneSaldi) itemDebitoCredito.Importo = itemDebitoCredito.Importo * -1; lista.Add(itemDebitoCredito); } } //============================================================================================================== // Rielaboro lista finale //============================================================================================================== try { // Tolgo gli elementi FAKE aggiunti per permettere l'inserimento di tutti i saldi e versamenti IList<ReportRipartizioneBilancioDTO> listaRiparto = (lista.Where(item => item.CodiceConto != "666")).ToList(); // I Millesimi deve comparire solo sul primo soggetto per una stessa unità immmobiliare (bugid#1002) var listaContoGroup = listaRiparto.GroupBy(item => item.IdConto).Select(contoGroup => contoGroup); foreach (var itemGroup in listaContoGroup) { var listaUnitaGroup = itemGroup.GroupBy(item => item.IdUnitaImmobiliare).Select(unitaGroup => unitaGroup); foreach (var unitaGroup in listaUnitaGroup) { var first = true; foreach (var item in unitaGroup.OrderByDescending(item2 => item2.TipoNominativo).ThenBy(item2 => item2.Nominativo)) { if (!first) item.Millesimi = null; first = false; } } } //============================================================================================================== // Applico eventuali accorpamenti //============================================================================================================== if (!accorpamentoUnita) listaRiparto = elaboraAccorpamento(listaRiparto, tipoAccorpamento, soggettiAttivi, null, null, null, null); //============================================================================================================== // Elimino righe per conti vuoti //============================================================================================================== listaRiparto = elaboraRigheContiVuoti(listaRiparto); //============================================================================================================== // Aggiungo colonna spese conduzione //============================================================================================================== var listaConduzione = listaRiparto.Where(item => item.OrdineConto < 9990 && item.TipoNominativo == "COND").GroupBy(item => item.IdPartecipante).ToList(); foreach (var item in listaConduzione) { var firstItem = item.FirstOrDefault(); if (firstItem != null) { // Debito var itemConduzione = cloneItem(firstItem); itemConduzione.IdConto = 0; itemConduzione.CodiceConto = null; itemConduzione.IdSottoConto = null; itemConduzione.CodiceSottoConto = null; itemConduzione.Importo = item.Sum(itemImporto => itemImporto.Importo); itemConduzione.TipoNominativo = "COND"; itemConduzione.TipoNominativoEffettivo = firstItem.TipoNominativoEffettivo; itemConduzione.DescrizioneConto = "Spese Conduzione"; itemConduzione.OrdineConto = 9996; listaRiparto.Add(itemConduzione); lista.Add(itemConduzione); } } //============================================================================================================== // ARROTONDAMENTO Importi generazione di una nuova riga di arrotondamenti //============================================================================================================== var importiNonArrotondati = new List<ReportRipartizioneBilancioDTO>(); foreach (var reportRipartizioneBilancioDTO in listaRiparto.Where(item => item.OrdineConto < 9990)) { if (reportRipartizioneBilancioDTO.Importo != null) { var importoArrotondato = Math.Round(reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(), 2); var importoArrotondamento = reportRipartizioneBilancioDTO.Importo.GetValueOrDefault() - importoArrotondato; var itemImportoArrotondato = importiNonArrotondati.FirstOrDefault(item => item.IdConto == reportRipartizioneBilancioDTO.IdConto && item.DescrizioneConto == reportRipartizioneBilancioDTO.DescrizioneConto); if (itemImportoArrotondato == null) { itemImportoArrotondato = getItemArrotondamenti(reportRipartizioneBilancioDTO); itemImportoArrotondato.Importo = importoArrotondamento; importiNonArrotondati.Add(itemImportoArrotondato); } else itemImportoArrotondato.Importo += importoArrotondamento; // Aggiorno gli importi a due decimali bugid#3091 reportRipartizioneBilancioDTO.Importo = importoArrotondato; } } // Aggiungo anche il totale degli arrotondamenti var totaleArrotondamento = 0m; foreach (var reportRipartizioneBilancioDTO in importiNonArrotondati) { reportRipartizioneBilancioDTO.Importo = Math.Round(reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(), 2); totaleArrotondamento += reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(); } if (totaleArrotondamento != 0) { var itemImportoArrotondato = getItemArrotondamenti(importiNonArrotondati.FirstOrDefault()); itemImportoArrotondato.OrdineConto = 9990; itemImportoArrotondato.IdConto = 0; itemImportoArrotondato.DescrizioneConto = "Totale Spese"; itemImportoArrotondato.Importo = totaleArrotondamento; importiNonArrotondati.Add(itemImportoArrotondato); var itemImportoArrotondatoDebitoCredito = getItemArrotondamenti(importiNonArrotondati.FirstOrDefault()); itemImportoArrotondatoDebitoCredito.IdConto = 0; itemImportoArrotondatoDebitoCredito.Importo = totaleArrotondamento; if (inversioneSaldi) itemImportoArrotondatoDebitoCredito.Importo = itemImportoArrotondatoDebitoCredito.Importo * -1; if (totaleArrotondamento < 0) { itemImportoArrotondatoDebitoCredito.OrdineConto = 9994; itemImportoArrotondatoDebitoCredito.DescrizioneConto = "a Credito"; } else { itemImportoArrotondatoDebitoCredito.OrdineConto = 9993; itemImportoArrotondatoDebitoCredito.DescrizioneConto = "a Debito"; } importiNonArrotondati.Add(itemImportoArrotondatoDebitoCredito); } foreach (var reportRipartizioneBilancioDTO in importiNonArrotondati) { listaRiparto.Add(reportRipartizioneBilancioDTO); } // ====================================================== // Add Empty items - Per una corretta visualizzazione // nel report multicolonna // ====================================================== if (!ripartizioneProprietarioConduttore && !dettaglioSottoConto) { var emptyItems = getEmptyItems(listaRiparto); foreach (var reportRipartizioneBilancioDTO in emptyItems) listaRiparto.Add(reportRipartizioneBilancioDTO); } // ====================================================== // Rielaborazione millesimi // ====================================================== elaborazioneMillesimi(listaRiparto); // ====================================================== // Ritorno solo le righe dei condomini selezionati // ====================================================== if (idSoggetti != null) listaRiparto = listaRiparto.Where(item => idSoggetti.Contains(item.IdPartecipante)).ToList(); return listaRiparto.OrderBy(item => item.IdGruppoStabile); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del preventivo - RIELABORAZIONE LISTA FINALE - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio); throw; } } return null; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato durante la lettura del datasource per il riparto del preventivo - {0} - esercizio:{1} - stabile:{2} - scala:{3} - ripartizioneProprietarioConduttore:{4} - accorpamentoUnita:{5} - inversioneSaldi:{6}", ex, Utility.GetMethodDescription(), idEsercizio, idStabile.GetValueOrDefault(), idScala.GetValueOrDefault(), ripartizioneProprietarioConduttore, tipoAccorpamento, inversioneSaldi); throw; } }
private ReportRipartizioneBilancioDTO getItemArrotondamenti(ReportRipartizioneBilancioDTO reportRipartizioneBilancioDTO) { var item = new ReportRipartizioneBilancioDTO { IdConto = reportRipartizioneBilancioDTO.IdConto, DescrizioneConto = reportRipartizioneBilancioDTO.DescrizioneConto, OrdineConto = reportRipartizioneBilancioDTO.OrdineConto, DisabilitaStampaMillesimi = true, DescrizioneStabile = "Arrotondamenti", OrdineStabile = int.MaxValue, IdGruppoStabile = int.MaxValue, DescrizioneGruppoStabile = "Arrotondamenti", OrdineUnitaImmobiliare = int.MaxValue, Nominativo = "Arrotondamenti", OrdinePartecipante = int.MaxValue, TipoNominativo = "PROP", TipoNominativoEffettivo = "P" }; return item; }
private RiepilogoRipartoDTO setRiepilogoRiparto(ReportRipartizioneBilancioDTO reportRipartizioneBilancioDTO, Esercizio esercizio) { try { var unitaImmobiliare = _daoFactory.GetUnitaImmobiliareDao().Find(reportRipartizioneBilancioDTO.IdUnitaImmobiliare, false); if (unitaImmobiliare != null) { var riepilogoPreventivo = new RiepilogoRipartoDTO { CodiceTipoUnita = unitaImmobiliare.TipoUnitaImmobiliare.ID, DescrizioneTipoUnita = reportRipartizioneBilancioDTO.TipoUnitaImmobiliare, DescrizioneUnitaImmobiliare = unitaImmobiliare.Descrizione, IdPersona = reportRipartizioneBilancioDTO.IdPersona, IdSoggettoCondominio = reportRipartizioneBilancioDTO.IdPartecipante, IdUnitaImmobiliare = reportRipartizioneBilancioDTO.IdUnitaImmobiliare, Importo = getImporto(reportRipartizioneBilancioDTO.Importo.GetValueOrDefault(), esercizio), Interno = reportRipartizioneBilancioDTO.InternoUnitaImmobiliare, Nominativo = reportRipartizioneBilancioDTO.Nominativo, OrdineUnitaImmobiliare = reportRipartizioneBilancioDTO.OrdineUnitaImmobiliare, Subalterno = reportRipartizioneBilancioDTO.SubalternoUnitaImmobiliare, TipoSoggettoCondominio = reportRipartizioneBilancioDTO.TipoNominativoEffettivo == "P" ? TipoSoggetto.Proprietario : TipoSoggetto.Conduttore }; return riepilogoPreventivo; } else { _log.ErrorFormat("Non trovato unità immobiliare - {0} idUnita:{1}", Utility.GetMethodDescription(), reportRipartizioneBilancioDTO.IdUnitaImmobiliare); throw new InvalidDataException($"Non trovata unità immobiliare id#{reportRipartizioneBilancioDTO.IdUnitaImmobiliare}"); } } catch (Exception ex) { _log.ErrorFormat("Errore nel riepilogo del riparto - {0} - unità immobiliare:{1} - esercizio:{2}", ex, Utility.GetMethodDescription(), reportRipartizioneBilancioDTO.IdUnitaImmobiliare, esercizio?.ID.ToString() ?? "<NULL>"); throw; } }
/* private IStampeService getStampeService() { return _stampeService ?? (_stampeService = ResolveComponent<IStampeService>()); } */ #endregion Service #region Helper Methods private void setBorder(ReportRipartizioneBilancioDTO itemReport, XRTableCell cell, List<IGrouping<string, ReportRipartizioneBilancioDTO>> dataSource, int indexItem, int idPartecipantePrecedente) { var skip = false; if (itemReport.TipoNominativo == "PROP") { try { if (dataSource.Count > indexItem + 1) { var nextNominativo = dataSource[indexItem + 1].OrderBy(item => itemReport.OrdineConto).FirstOrDefault(); if (nextNominativo != null && itemReport.IdPartecipante != nextNominativo.IdPartecipante) skip = true; } } catch (Exception ex) { _log.ErrorFormat("Errore nell'impostazione del border - {0} - azienda:{1}", ex, Utility.GetMethodDescription(), Security.Login.Instance.CurrentLogin().Azienda); throw; } } if (!skip) { if (_impostazioniReport.BorderInsideGroup && (itemReport.TipoNominativo == "PROP" || itemReport.IdPartecipante == idPartecipantePrecedente)) setCellBorder(cell, dataSource.Count, indexItem, itemReport.IdPartecipante == idPartecipantePrecedente); } }
public object Clone() { var item = new ReportRipartizioneBilancioDTO { IdConto = IdConto, CodiceConto = CodiceConto, DescrizioneConto = DescrizioneConto, OrdineConto = OrdineConto, IdSottoConto = IdSottoConto, CodiceSottoConto = CodiceSottoConto, DescrizioneSottoConto = DescrizioneSottoConto, DisabilitaStampaMillesimi = DisabilitaStampaMillesimi, IdUnitaImmobiliare = IdUnitaImmobiliare, OrdineUnitaImmobiliare = OrdineUnitaImmobiliare, InternoUnitaImmobiliare = InternoUnitaImmobiliare, TipoUnitaImmobiliare = TipoUnitaImmobiliare, IdGruppoStabile = IdGruppoStabile, DescrizioneGruppoStabile = DescrizioneGruppoStabile, OrdineGruppoStabile = OrdineGruppoStabile, IdStabile = IdStabile, DescrizioneStabile = DescrizioneStabile, OrdineStabile = OrdineStabile, IdRendiconto = IdRendiconto, TipoNominativo = TipoNominativo, TipoNominativoEffettivo = TipoNominativoEffettivo, Importo = Importo, MillesimiProprieta = MillesimiProprieta, Millesimi = Millesimi, UnitaMisuraMillesimi = UnitaMisuraMillesimi, NumeroColonne = NumeroColonne, SubalternoUnitaImmobiliare = SubalternoUnitaImmobiliare, IdPartecipante = IdPartecipante, OrdinePartecipante = OrdinePartecipante, IdPersona = IdPersona, Nominativo = Nominativo }; return item; }