/// <summary> /// Crea un Riparto Bollette valido /// </summary> public RipartoBollette(TestataRipartoBollette testata, UnitaImmobiliare unita) { UnitaImmobiliare = unita; Testata = testata; if (Testata != null) Testata.Riparto.Add(this); }
public IList<ImportiDTO> CalcolaAddebito(Esercizio esercizio, TipoUtenza tipoUtenza, IList<LetturaContatoreCalcoloDTO> consumi, string descrizioneMovimentoAcqua, string descrizioneMovimentoRiscaldamento, int? idContoAcquaRiscaldata, int? idContoRiscaldamento, int? idContoMillesimiSpalo, decimal? tariffaRiscaldamentoAcqua, decimal? tariffaAcquaFredda, bool salvaRiparto, DateTime dataRegistrazione, bool clearRiparto) { try { _ripartoBollette.Clear(); var importiAddebito = new List<ImportiDTO>(); if (consumi.Count > 0 && esercizio != null) { TestataRipartoBollette testata = null; // ================================================== // Elimino eventuali vecchi riparti // ================================================== if (clearRiparto && salvaRiparto) ClearCalcoloAddebito(esercizio, tipoUtenza); else testata = _daoFactory.GetTestataRipartoBolletteDao().GetByEsercizioTipoUtenza(esercizio.ID, tipoUtenza.ID).FirstOrDefault(); // ================================================== // Raggruppo per unità per calcolare i consumi totali // ================================================== // Raggruppo le letture per unità immobiliare var letturePerUnita = (from item in consumi group item by item.IdUnitaImmobiliare into g select new ConsumoUnita(g.Key, g.Sum(item => item.Valore.GetValueOrDefault()), g.Count())).ToList(); // ================================================== // Calcolo addebiti per unità // ================================================== importiAddebito = new List<ImportiDTO>(letturePerUnita.Count()); if (testata == null) { testata = new TestataRipartoBollette(esercizio, tipoUtenza, dataRegistrazione) { DescrizioneMovimentoAcqua = descrizioneMovimentoAcqua, DescrizioneMovimentoRiscaldamento = descrizioneMovimentoRiscaldamento }; } if (idContoAcquaRiscaldata != null) testata.ContoAcquaRiscaldamento = _daoFactory.GetContoDao().GetById(idContoAcquaRiscaldata.GetValueOrDefault(), false); if (idContoRiscaldamento != null) testata.ContoRiscaldamento = _daoFactory.GetContoDao().GetById(idContoRiscaldamento.GetValueOrDefault(), false); if (idContoMillesimiSpalo != null) testata.ContoSpalo = _daoFactory.GetContoDao().GetById(idContoMillesimiSpalo.GetValueOrDefault(), false); if (tariffaRiscaldamentoAcqua != null) testata.TariffaRiscaldamentoAcqua = tariffaRiscaldamentoAcqua; if (tariffaAcquaFredda != null) testata.TariffaAcquaFredda = tariffaAcquaFredda; _daoFactory.GetTestataRipartoBolletteDao().SaveOrUpdate(testata); foreach (var consumoUnita in letturePerUnita) { try { var unita = _daoFactory.GetUnitaImmobiliareDao().GetById(consumoUnita.IdUnitaImmobiliare, false); if (salvaRiparto) { var riparto = new RipartoBollette(testata, unita); _ripartoBollette.Add(riparto); _daoFactory.GetRipartoBolletteDao().SaveOrUpdate(riparto); } //=============================== // CONSUMO //=============================== var importoConsumo = consumoUnita.ConsumoTotale*tariffaAcquaFredda; //=============================== // TOTALI //=============================== importiAddebito.Add(new ImportiDTO(unita.ID, importoConsumo.GetValueOrDefault())); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - UNITA' IMMOBILIARE {0} - unità immobiliare:{1}", ex, Library.Utility.GetMethodDescription(), consumoUnita.IdUnitaImmobiliare); throw; } } } return importiAddebito; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - {0} - esercizio:{1} - tipo utenza:{2}", ex, Library.Utility.GetMethodDescription(), esercizio != null ? esercizio.ID.ToString() : "<NULL>", tipoUtenza); throw; } }
public IList<ImportiDTO> CalcolaAddebito(Esercizio esercizio, TipoUtenza tipoUtenza, IList<LetturaContatoreCalcoloDTO> consumi, string descrizioneMovimentoAcqua, string descrizioneMovimentoRiscaldamento, int? idContoAcquaRiscaldata, int? idContoRiscaldamento, int? idContoMillesimiSpalo, decimal? tariffaRiscaldamentoAcqua, decimal? tariffaAcquaFredda, bool salvaRiparto, DateTime dataRegistrazione, bool clearRiparto) { try { var importiAddebito = new List<ImportiDTO>(); _ripartoBollette = new List<RipartoBollette>(); if (consumi.Count > 0 && esercizio != null) { // ================================================== // Elimino eventuali vecchi riparti // ================================================== if (clearRiparto && salvaRiparto && _testataRipartoBollette == null) ClearCalcoloAddebito(esercizio, tipoUtenza); else _testataRipartoBollette = _daoFactory.GetTestataRipartoBolletteDao().GetByEsercizioTipoUtenza(esercizio.ID, tipoUtenza.ID).FirstOrDefault(); // ================================================== // Individuo il tariffario da applicare // ================================================== var condominio = esercizio.CondominioRiferimento; var tariffa = condominio.Indirizzo.Comune.TariffaAcqua; if (tariffa == null) { var ex = new Exception($"Non è stata trovata nessuna tariffa per il comune: {condominio.Indirizzo.Comune.Descrizione}"); _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - {0}", ex, Library.Utility.GetMethodDescription()); throw (ex); } // ================================================== // Raggruppo per unità per calcolare i consumi totali // ================================================== // Raggruppo i consumi per unità immobiliare var consumiPerUnita = (from item in consumi group item by item.IdUnitaImmobiliare into g select new ConsumoUnita(g.Key, g.Sum(item => item.Valore.GetValueOrDefault()), g.Count())).ToList(); var fasceConsumo = _daoFactory.GetFasciaConsumoDettaglioDao().GetByTariffaTipo(tariffa, Sfera.Enums.TipoDettaglioBollettaEnum.Consumo); var fasceConsumoQuotaFissa = _daoFactory.GetFasciaConsumoDettaglioDao().GetByTariffaTipo(tariffa, Sfera.Enums.TipoDettaglioBollettaEnum.QuotaFissa); // ================================================== // Calcolo addebiti per unità // ================================================== importiAddebito = new List<ImportiDTO>(consumiPerUnita.Count); if (_testataRipartoBollette == null) { _testataRipartoBollette = new TestataRipartoBollette(esercizio, tipoUtenza, dataRegistrazione) { DescrizioneMovimentoAcqua = descrizioneMovimentoAcqua, DescrizioneMovimentoRiscaldamento = descrizioneMovimentoRiscaldamento }; } if(idContoAcquaRiscaldata != null) _testataRipartoBollette.ContoAcquaRiscaldamento = _daoFactory.GetContoDao().GetById(idContoAcquaRiscaldata.GetValueOrDefault(), false); if (idContoRiscaldamento != null) _testataRipartoBollette.ContoRiscaldamento = _daoFactory.GetContoDao().GetById(idContoRiscaldamento.GetValueOrDefault(), false); if (idContoMillesimiSpalo != null) _testataRipartoBollette.ContoSpalo = _daoFactory.GetContoDao().GetById(idContoMillesimiSpalo.GetValueOrDefault(), false); if (tariffaRiscaldamentoAcqua != null) _testataRipartoBollette.TariffaRiscaldamentoAcqua = tariffaRiscaldamentoAcqua; _daoFactory.GetTestataRipartoBolletteDao().SaveOrUpdate(_testataRipartoBollette); foreach (var consumoUnita in consumiPerUnita) { try { var numeroResidenti = 2; UnitaImmobiliare unita = null; if (consumoUnita.IdUnitaImmobiliare > 0) { unita = _daoFactory.GetUnitaImmobiliareDao().GetById(consumoUnita.IdUnitaImmobiliare, false); if (unita.NumeroResidenti > 0) numeroResidenti = unita.NumeroResidenti; } RipartoBollette riparto = null; if (salvaRiparto) { riparto = new RipartoBollette(_testataRipartoBollette, unita) { ConsumoAcquaCalda = 0, ImportoAcquaCalda = 0 }; _ripartoBollette.Add(riparto); _daoFactory.GetRipartoBolletteDao().SaveOrUpdate(riparto); } var fasceConsumoUnita = from item in fasceConsumo where item.NumeroComponenti == numeroResidenti orderby item.ValoreMinimo select item; //=============================== // CONSUMO //=============================== // ---------------------------------------------------------------------------- // Loop per tutte le fasce per trovare i consumi da addebitare per ogni fascia // ---------------------------------------------------------------------------- var consumoResiduo = (consumoUnita.ConsumoTotale * 1000) / consumoUnita.Giorni; decimal importoConsumo = 0; decimal consumoMassimoFasciaPrecedente = 0; foreach (var dettaglioFascia in fasceConsumoUnita) { try { if (consumoResiduo == 0) break; // tariffa per fascia attuale decimal importoTariffa = 0; var singolaTariffa = (from item in tariffa.Tariffe where item.Tipo == Sfera.Enums.TipoDettaglioBollettaEnum.Consumo && item.FasciaConsumo.ID == dettaglioFascia.Fascia.ID select item).SingleOrDefault(); if (singolaTariffa != null) importoTariffa = singolaTariffa.Valore; // consumo (litri/gg) di competenza di questa fascia var consumoPerFascia = consumoResiduo; var consumoMassimoPerFascia = dettaglioFascia.ValoreMassimo - consumoMassimoFasciaPrecedente; if (consumoMassimoPerFascia < consumoPerFascia) consumoPerFascia = consumoMassimoPerFascia; // calcolo addebito (la tariffa è indicata per mc) var importoPerFascia = (consumoPerFascia * consumoUnita.Giorni) / 1000 * importoTariffa; importoConsumo += importoPerFascia; if (salvaRiparto) new RipartoBolletteDettaglio(riparto, dettaglioFascia, (consumoPerFascia * consumoUnita.Giorni) / 1000, importoPerFascia); consumoResiduo -= consumoPerFascia; consumoMassimoFasciaPrecedente = dettaglioFascia.ValoreMassimo; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - DETTAGLIO FASCIA - {0} - unità immobiliare:{1} - dettaglio fascia:{2}", ex, Library.Utility.GetMethodDescription(), consumoUnita.IdUnitaImmobiliare, dettaglioFascia.ID); throw; } } //=============================== // Quota Fissa //=============================== var quotaFissa = 0m; if(unita != null && !unita.EsclusaAddebitoQuotaFissa) quotaFissa = calcoloQuotaFissa(unita, consumoUnita.ConsumoTotale, fasceConsumoQuotaFissa); if (riparto != null) riparto.QuotaFissa = quotaFissa; //=============================== // Fognatura //=============================== decimal importoTariffaFognatura = 0; var singolaTariffaFognatura = (from item in tariffa.Tariffe where item.Tipo == Sfera.Enums.TipoDettaglioBollettaEnum.Fognatura select item).SingleOrDefault(); if (singolaTariffaFognatura != null) importoTariffaFognatura = singolaTariffaFognatura.Valore; var importoFognatura = consumoUnita.ConsumoTotale*importoTariffaFognatura; if (riparto != null) riparto.Fognatura = importoFognatura; //=============================== // Depurazione //=============================== decimal importoTariffaDepurazione = 0; var singolaTariffaDepurazione = (from item in tariffa.Tariffe where item.Tipo == Sfera.Enums.TipoDettaglioBollettaEnum.Depurazione select item).SingleOrDefault(); if (singolaTariffaDepurazione != null) importoTariffaDepurazione = singolaTariffaDepurazione.Valore; var importoDepurazione = consumoUnita.ConsumoTotale*importoTariffaDepurazione; if (riparto != null) riparto.Depurazione = importoDepurazione; //=============================== // TOTALI //=============================== var importoImponibile = importoConsumo + quotaFissa + importoFognatura + importoDepurazione; var importoIva = importoImponibile * 0.10m; if (riparto != null) riparto.ImportoIva = importoIva; importiAddebito.Add(new ImportiDTO(consumoUnita.IdUnitaImmobiliare, importoImponibile + importoIva)); } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - UNITA' IMMOBILIARE {0} - unità immobiliare:{1}", ex, Library.Utility.GetMethodDescription(), consumoUnita.IdUnitaImmobiliare); throw; } } } return importiAddebito; } catch (Exception ex) { _log.ErrorFormat("Errore inaspettato nel calcolo dell'addebito bolletta - {0} - esercizio:{1} - tipo utenza:{2}", ex, Library.Utility.GetMethodDescription(), esercizio?.ID.ToString() ?? "<NULL>", tipoUtenza); throw; } }
public AuthorizationMessages CalcoloRipartoAcqua(int idEsercizio, TipoUtenza tipoUtenza, int? idContoAcquaRiscaldata, int? idContoRiscaldamento, int? idContoMillesimiSpalo, string descrizioneMovimentoAcqua, string descrizioneMovimentoRiscaldamento, decimal? tariffaRiscaldamentoAcqua, decimal? tariffaAcquaFredda, IList<ParametriAddebitoMovimento> parametriAddebitoMovimenti, DateTime? dataRegistrazione) { try { if(!Library.Conversione.IsSqlSmallDateTime(dataRegistrazione.GetValueOrDefault())) return new AuthorizationMessages("Non è possibile procedere al riparto delle bollette verificare la corettezza della data di registrazione: " + dataRegistrazione.GetValueOrDefault(), null); var fatalMessage = string.Empty; var warnMessage = string.Empty; var messaggioContatore = string.Empty; var esercizio = _daoFactory.GetEsercizioDao().GetById(idEsercizio, false); var utenze = _daoFactory.GetUtenzaDao().GetByCondominioTipo(esercizio.CondominioRiferimento, tipoUtenza).Where(item => item.IsAllowRipartoLetture()).ToList(); var soggettiAttivi = _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizio(esercizio, null); // =========================================== // Controllo presenza bollette // =========================================== var spesePresenti = false; var dictSpese = new Dictionary<int, IList<Spesa>>(); foreach (var utenza in utenze) { const string hql = "FROM Spesa SPE WHERE SPE.Utenza.RipartoLetture = 1 AND SPE.Utenza = :utenza AND SPE.EsercizioRiferimento = :esercizio"; var spese = _daoFactory.GetSpesaDao().GetByQuery(hql, new[] { new QueryParam("utenza", utenza), new QueryParam("esercizio", idEsercizio) }); // Controllo se tutte le bollette hanno la data di inizio e fine competenza if (spese.Any(item => item.DataInizioCompetenza == null || item.DataFineCompetenza == null)) { var speseSenzaCompetenza = spese.Where(item => item.DataInizioCompetenza == null || item.DataFineCompetenza == null); fatalMessage = speseSenzaCompetenza.Aggregate(fatalMessage, (current, spesa) => current + ("Per La bolletta n." + spesa.NumeroDocumento + " del " + spesa.DataDocumento.GetValueOrDefault().ToShortDateString() + " non è stata definita la competenza." + Environment.NewLine)); _persistenceContext.RollbackAndCloseSession(Security.Login.Instance.CurrentLogin().LoginName); _persistenceContext.BeginTransaction(Security.Login.Instance.CurrentLogin().LoginName, IsolationLevel.ReadUncommitted); return new AuthorizationMessages(fatalMessage, warnMessage); } if (spese.Any(item => item.ImportoBolletta != 0)) spesePresenti = true; dictSpese.Add(utenza.ID, spese); } if (!spesePresenti) { fatalMessage += "Non sono presenti bollette da ripartire"; _persistenceContext.RollbackAndCloseSession(Security.Login.Instance.CurrentLogin().LoginName); _persistenceContext.BeginTransaction(Security.Login.Instance.CurrentLogin().LoginName, IsolationLevel.ReadUncommitted); return new AuthorizationMessages(fatalMessage, warnMessage); } // =========================================== // Se non ci sono errori elaboro tutte le utenze // =========================================== foreach (var utenza in utenze) { DateTime? dataInizialeSpese = null; DateTime? dataFinaleSpese = null; DateTime? dataInizialeLetture = null; DateTime? dataFinaleLetture = null; var spese = dictSpese[utenza.ID]; spesePresenti = spese.Any(item => item.ImportoBolletta != 0); if (spesePresenti) { dataInizialeSpese = spese.Min(item => item.DataInizioCompetenza).Value; dataFinaleSpese = spese.Max(item => item.DataFineCompetenza).Value; } var lettureDate = new List<LetturaContatore>(); // Verifico le letture dei contatori escludendo quelli che prevedono un riparto lineare foreach (var contatore in utenza.Contatori.Where(item => !item.IsContaCalorie)) lettureDate.AddRange(GetLettureByEsercizio(idEsercizio, contatore.ID)); var datiPresenti = false; if (lettureDate.Count > 0) { datiPresenti = true; dataInizialeLetture = lettureDate.Min(item => item.Data); dataFinaleLetture = lettureDate.Max(item => item.Data); } if (datiPresenti && spesePresenti) { // ========================================================= // Calcolo consumi e addebiti la competenza delle bollette // ========================================================= var consumiAcquaCaldaLista = new List<List<ConsumoUnita>>(); var consumiTotali = new List<LetturaContatoreCalcoloDTO>(); // Calcolo consumo per ogni contatore var letturePerContatore = new Dictionary<int, IList<LetturaContatoreCalcoloDTO>>(); var consumiPerContatore = new Dictionary<int, IList<LetturaContatoreCalcoloDTO>>(); foreach (var contatore in utenza.Contatori) { try { DateTime dataIniziale; DateTime dataFinale; if (contatore.Tipo.TipoCalcolo != TipoCalcoloContatoreEnum.AcquaCalda) { dataIniziale = dataInizialeSpese.Value; dataFinale = dataFinaleSpese.Value; } else { dataIniziale = dataInizialeLetture.Value; dataFinale = dataFinaleLetture.Value; } var letture = getLettureCalcoloByContatoreData(contatore, dataIniziale, dataFinale); letturePerContatore.Add(contatore.ID, letture); var consumi = getConsumoGiornaliero(contatore.ID, letture, dataIniziale, dataFinale); // Se non sono stati calcolati consumi per il contatore considerato memorizzo il messaggio per eventualmente visualizzarlo all'utente if (consumi.Count == 0) { messaggioContatore += "Non sono stati trovate sufficienti letture per il Contatore: " + contatore.Codice + " - " + contatore.Descrizione + " - Utenza: " + utenza.Numero + " - " + utenza.Descrizione; } consumiPerContatore.Add(contatore.ID, consumi); if (contatore.Tipo.TipoCalcolo == TipoCalcoloContatoreEnum.AcquaCalda) { // ================================================== // Raggruppo per unità per calcolare i consumi totali // ================================================== // Raggruppo i consumi per unità immobiliare var consumiPerUnita = from item in consumi group item by item.IdUnitaImmobiliare into g select new ConsumoUnita(g.Key, g.Sum(item => item.Valore.GetValueOrDefault()), g.Count()); consumiAcquaCaldaLista.Add(consumiPerUnita.ToList()); } foreach (var consumo in consumi) { var consumoTotale = (from item in consumiTotali where item.IdUnitaImmobiliare == consumo.IdUnitaImmobiliare && item.Data == consumo.Data select item).SingleOrDefault(); if (consumoTotale != null) consumoTotale.Valore += consumo.Valore; else consumiTotali.Add(consumo); } } catch (Exception ex) { _log.ErrorFormat("Errore durante il calcolo del consumo giornaliero (SINGOLO CONTATORE) - {0} - contatore:{1}", ex, Library.Utility.GetMethodDescription(), contatore.ID); throw; } } // Con la somma dei consumi giornalieri per contatore calcolo l'addebito var addebitiCalcolati = _calcoliUtenzaService.CalcolaAddebito(esercizio, tipoUtenza, consumiTotali, descrizioneMovimentoAcqua, descrizioneMovimentoRiscaldamento, idContoAcquaRiscaldata, idContoRiscaldamento, idContoMillesimiSpalo, tariffaRiscaldamentoAcqua, tariffaAcquaFredda, true, dataRegistrazione.GetValueOrDefault()); // Se non sono riuscito a calcolare addebiti il riparto è fallito, visualizzo eventuali messaggi relativi ai singoli contatori come messaggi fatal if (addebitiCalcolati.Count == 0) { fatalMessage += messaggioContatore; messaggioContatore = null; } else { warnMessage += messaggioContatore; messaggioContatore = null; } // Aggiorno letture utilizzate foreach (var riparto in _calcoliUtenzaService.GetRipartoBollette()) { foreach (var kvp in consumiPerContatore) { try { // ----------------------------------------------------------------------------------- // Se il contatore è condominiale non lo considero nei consumi dei contatori divisionali, viceversa per i conumi del contatore condominiale var contatore = _daoFactory.GetContatoreDao().GetById(kvp.Key, false); if (contatore.IsCondominiale && riparto.UnitaImmobiliare != null) continue; if (!contatore.IsCondominiale && riparto.UnitaImmobiliare == null) continue; // ----------------------------------------------------------------------------------- var lettureUtilizzate = letturePerContatore[kvp.Key]; // ================================================================= // Lettura iniziale // ================================================================= var riparto1 = riparto; var listaLettureIniziali = new SortedList<int, LetturaContatoreCalcoloDTO>(); foreach ( var letturaContatoreCalcoloDTO in lettureUtilizzate.Where( item => (item.IdUnitaImmobiliare < 0 && riparto1.UnitaImmobiliare == null) || (item.IdUnitaImmobiliare == riparto1.UnitaImmobiliare.ID))) listaLettureIniziali.Add( Math.Abs( (esercizio.DataApertura.GetValueOrDefault() - letturaContatoreCalcoloDTO.Data).Days), letturaContatoreCalcoloDTO); var letturaIniziale = listaLettureIniziali.Values.FirstOrDefault(); if (letturaIniziale == null) { var idUnitaImmobiliare = "<NULL>"; if (riparto.UnitaImmobiliare != null) idUnitaImmobiliare = riparto.UnitaImmobiliare.ID.ToString(); _log.Error("Le letture non sono sufficienti per poter effettuare il riparto: " + Library.Utility.GetMethodDescription() + " - Lettura Iniziale - idUnitaImmobiliare: " + idUnitaImmobiliare + " - idEsercizio: " + idEsercizio + " - tipoUtenza: " + tipoUtenza); _persistenceContext.RollbackAndCloseSession( Security.Login.Instance.CurrentLogin().LoginName); _persistenceContext.BeginTransaction( Security.Login.Instance.CurrentLogin().LoginName, IsolationLevel.ReadUncommitted); return new AuthorizationMessages("Le letture non sono sufficienti per poter effettuare il riparto" + Environment.NewLine + fatalMessage, warnMessage); } var valoreLetturaIniziale = letturaIniziale.Valore.GetValueOrDefault(); var tipoLetturaIniziale = TipoLetturaEnum.Effettiva; // ================================================================= // Lettura finale // ================================================================= var listaLettureFinali = new SortedList<int, LetturaContatoreCalcoloDTO>(); foreach ( var letturaContatoreCalcoloDTO in lettureUtilizzate.Where( item => (item.IdUnitaImmobiliare < 0 && riparto1.UnitaImmobiliare == null) || (item.IdUnitaImmobiliare == riparto1.UnitaImmobiliare.ID))) listaLettureFinali.Add( Math.Abs( (esercizio.DataChiusura.GetValueOrDefault() - letturaContatoreCalcoloDTO.Data).Days), letturaContatoreCalcoloDTO); var letturaFinale = listaLettureFinali.Values.FirstOrDefault(); if (letturaFinale == null) { var idUnitaImmobiliare = "<NULL>"; if (riparto.UnitaImmobiliare != null) idUnitaImmobiliare = riparto.UnitaImmobiliare.ID.ToString(); _log.Error("Le letture non sono sufficienti per poter effettuare il riparto: " + Library.Utility.GetMethodDescription() + " - Lettura Finale - idUnitaImmobiliare: " + idUnitaImmobiliare + " - idEsercizio: " + idEsercizio + " - tipoUtenza: " + tipoUtenza); _persistenceContext.RollbackAndCloseSession( Security.Login.Instance.CurrentLogin().LoginName); _persistenceContext.BeginTransaction( Security.Login.Instance.CurrentLogin().LoginName, IsolationLevel.ReadUncommitted); return new AuthorizationMessages( "Le letture non sono sufficienti per poter effettuare il riparto" + Environment.NewLine + fatalMessage, warnMessage); } var valoreLetturaFinale = letturaFinale.Valore.GetValueOrDefault(); var tipoLetturaFinale = TipoLetturaEnum.Effettiva; //if (letturaFinale.Data < dataFinaleTotale) //{ // var riparto2 = riparto; // var consumoPresunto = (from item in kvp.Value // where item.IdUnitaImmobiliare == riparto2.UnitaImmobiliare.ID && item.Data >= letturaFinale.Data && item.Data < dataFinaleTotale // select item).Sum(item => item.Valore.GetValueOrDefault()); // valoreLetturaFinale += consumoPresunto; // tipoLetturaFinale = TipoLetturaEnum.Presunta; //} // ================================================================= // Lettura cambio contatore // ================================================================= LetturaContatoreCalcoloDTO letturaCambioContatore = null; var letturaPrecedente = letturaIniziale; var lettureInizialeFinale = lettureUtilizzate.Where( item => (item.IdUnitaImmobiliare < 0 && riparto1.UnitaImmobiliare == null) || (item.IdUnitaImmobiliare == riparto1.UnitaImmobiliare.ID) && item.Data >= letturaIniziale.Data && item.Data <= letturaFinale.Data) .OrderBy(item => item.Data); foreach (var letturaContatoreCalcoloDTO in lettureInizialeFinale) { if (letturaContatoreCalcoloDTO.Valore < letturaPrecedente.Valore) letturaCambioContatore = letturaPrecedente; letturaPrecedente = letturaContatoreCalcoloDTO; } var lettura = new RipartoBolletteLetture(riparto, _daoFactory.GetContatoreDao().GetById(kvp.Key, false), valoreLetturaIniziale, tipoLetturaIniziale, valoreLetturaFinale, tipoLetturaFinale) { DataLetturaIniziale = letturaIniziale.Data, DataLetturaFinale = letturaFinale.Data }; if (letturaCambioContatore != null) { lettura.LetturaCambioContatore = letturaCambioContatore.Valore.GetValueOrDefault(); lettura.DataLetturaCambioContatore = letturaCambioContatore.Data; } _daoFactory.GetRipartoBolletteLettureDao().SaveOrUpdate(lettura); } catch (Exception ex) { _log.Error( "Errore durante il calcolo del riparto acqua di una bolletta (Singolo Dettaglio) - " + Library.Utility.GetMethodDescription() + " - key:" + kvp.Key + " - idEsercizio: " + idEsercizio + " - tipoUtenza: " + tipoUtenza + " - idContoAcquaRiscaldata:" + idContoAcquaRiscaldata.GetValueOrDefault() + " - idContoRiscaldamento:" + idContoRiscaldamento.GetValueOrDefault() + " - idContoMillesimiSpalo:" + idContoMillesimiSpalo.GetValueOrDefault() + " - descrizioneMovimentoAcqua:" + descrizioneMovimentoAcqua + " - descrizioneMovimentoRiscaldamento:" + descrizioneMovimentoRiscaldamento + " - tariffaRiscaldamentoAcqua:" + tariffaRiscaldamentoAcqua + " - dataRegistrazione:" + dataRegistrazione , ex); throw; } } } // =================================================================================== // Riparto separatamente le singole Bollette in percentuale sull'importo complessivo // =================================================================================== //const string hql = "FROM RipartoBollette RIP WHERE RIP.Esercizio = :esercizio"; var addebitiContatoriDivisionali = addebitiCalcolati.Where(item => item.Id > 0).ToList(); Conto contoMillesimiSpalo = null; if (idContoMillesimiSpalo != null) contoMillesimiSpalo = _daoFactory.GetContoDao().GetById( idContoMillesimiSpalo.Value, false); fatalMessage = spese.Select(spesa => setRipartoBolletta(spesa, addebitiContatoriDivisionali, contoMillesimiSpalo, spese.Sum(item => item.ImportoBolletta.GetValueOrDefault()), _calcoliUtenzaService.GetRipartoBollette(), soggettiAttivi)).Where(messaggio => !string.IsNullOrEmpty(messaggio)).Aggregate(fatalMessage, (current, messaggio) => current + (messaggio + Environment.NewLine)); // ========================================================= // Calcolo costi di riscaldamento dell'Acqua // ========================================================= // Merge tra tutte le lista di consumo acqua calda // ------------------------------------------------ var consumiAcquaCalda = new List<ConsumoUnita>(); if (consumiAcquaCaldaLista.Count > 0) { consumiAcquaCalda = consumiAcquaCaldaLista[0]; foreach (var t in consumiAcquaCaldaLista) { foreach (var consumo in t) { var primoConsumo = (from item in consumiAcquaCalda where item.IdUnitaImmobiliare == consumo.IdUnitaImmobiliare select item).SingleOrDefault(); if (primoConsumo.IdUnitaImmobiliare > 0) primoConsumo.ConsumoTotale += consumo.ConsumoTotale; else consumiAcquaCalda.Add(consumo); } } } // Calcolo importo del riscaldamento // ------------------------------------------------ if (tipoUtenza.IsAcqua && idContoRiscaldamento != null && idContoAcquaRiscaldata != null && tariffaRiscaldamentoAcqua != null) { // Elimino testate di vecchi riparti foreach (var testata in esercizio.TestateContabiliRipartoAcqua) { testata.EsercizioRiferimento.TestateContabili.Remove(testata); testata.EsercizioRiferimento = null; testata.EsercizioRipartoAcqua = null; } esercizio.TestateContabiliRipartoAcqua.Clear(); var testataRiparto = new TestataRipartoBollette(esercizio, tipoUtenza, dataRegistrazione) { DescrizioneMovimentoAcqua = descrizioneMovimentoAcqua, DescrizioneMovimentoRiscaldamento = descrizioneMovimentoRiscaldamento }; if (idContoAcquaRiscaldata != null) testataRiparto.ContoAcquaRiscaldamento =_daoFactory.GetContoDao().GetById(idContoAcquaRiscaldata.GetValueOrDefault(), false); if (idContoRiscaldamento != null) testataRiparto.ContoRiscaldamento = _daoFactory.GetContoDao().GetById(idContoRiscaldamento.GetValueOrDefault(), false); if (idContoMillesimiSpalo != null) testataRiparto.ContoSpalo = _daoFactory.GetContoDao().GetById(idContoMillesimiSpalo.GetValueOrDefault(), false); if (tariffaRiscaldamentoAcqua != null) testataRiparto.TariffaRiscaldamentoAcqua = tariffaRiscaldamentoAcqua; var importiRiscaldamento = new List<ImportiDTO>(consumiAcquaCalda.Count); var ripartoBollette = _calcoliUtenzaService.GetRipartoBollette(); foreach (var consumo in consumiAcquaCalda) { var riparto = (from item in ripartoBollette where item.UnitaImmobiliare.ID == consumo.IdUnitaImmobiliare select item).SingleOrDefault(); if (riparto != null) { riparto.ConsumoAcquaCalda += consumo.ConsumoTotale; riparto.ImportoAcquaCalda += consumo.ConsumoTotale*tariffaRiscaldamentoAcqua; } else { new RipartoBollette(testataRiparto, _daoFactory.GetUnitaImmobiliareDao().GetById(consumo.IdUnitaImmobiliare, false)) { ConsumoAcquaCalda = consumo.ConsumoTotale, ImportoAcquaCalda = consumo.ConsumoTotale*tariffaRiscaldamentoAcqua }; } importiRiscaldamento.Add(new ImportiDTO(consumo.IdUnitaImmobiliare, consumo.ConsumoTotale*tariffaRiscaldamentoAcqua.Value)); } var newTestata = _movimentoContabileService.SetMovimentiRiscaldamentoAcqua(esercizio, idContoAcquaRiscaldata.Value, idContoRiscaldamento.Value, descrizioneMovimentoAcqua, descrizioneMovimentoRiscaldamento, importiRiscaldamento, dataRegistrazione.Value); newTestata.EsercizioRipartoAcqua = esercizio; esercizio.TestateContabiliRipartoAcqua.Add(newTestata); } // ========================================================= // Calcolo importi contatori condominiali // ========================================================= // Elimino testate di vecchi riparti foreach (var testata in esercizio.TestateContabiliRipartoContatoreCondominiale) { testata.EsercizioRiferimento = null; testata.EsercizioRipartoContatoreCondominiale = null; } esercizio.TestateContabiliRipartoContatoreCondominiale.Clear(); // Elimino parametri contatore condominiale var parametriCondominiale = _daoFactory.GetTestataRipartoContatoreCondominialeDao().GetByEsercizio(idEsercizio); foreach (var testataRipartoContatoreCondominiale in parametriCondominiale) _daoFactory.GetTestataRipartoContatoreCondominialeDao() .Delete(testataRipartoContatoreCondominiale); var addebitiContatoriCondominiali = addebitiCalcolati.Where(item => item.Id < 0).ToList(); foreach (var importiDTO in addebitiContatoriCondominiali) { var dto = importiDTO; var parametriMovimento = parametriAddebitoMovimenti.FirstOrDefault(item => item.Id == dto.Id*-1); var contoAddebito = _daoFactory.GetContoDao().GetById(parametriMovimento.IdConto, false); var sottoContoAddebito = _daoFactory.GetSottoContoDao().GetById(parametriMovimento.IdSottoConto, false); var importoTotaleBollette = spese.Sum(item => item.ImportoBolletta.GetValueOrDefault()); var contiAddebito = new Dictionary<string, decimal>(); foreach (var spesa in spese) { foreach (var movimento in spesa.MovimentiBollette) { var key = getKeyContoSottoconto(movimento.ContoRiferimento, movimento.SottoContoRiferimento); if (contiAddebito.ContainsKey(key)) contiAddebito[key] += movimento.GetImportoConSegno().GetValueOrDefault(); else contiAddebito.Add(key, movimento.GetImportoConSegno().GetValueOrDefault()); } } var importiAccredito = new List<ImportoMovimento>(); foreach (var importoConto in contiAddebito) { var contoAry = importoConto.Key.Split('|'); var idConto = int.Parse(contoAry[0]); int? idSottoConto = null; if (int.Parse(contoAry[1]) > 0) idSottoConto = int.Parse(contoAry[1]); var importo = (importiDTO.Importo*importoConto.Value)/importoTotaleBollette; importiAccredito.Add(new ImportoMovimento(idConto, idSottoConto, importo)); } var testataMovimentiCondominiali = _movimentoContabileService.SetMovimentiContatoreCondominiale(esercizio, importiAccredito, addebitiContatoriDivisionali, dataRegistrazione.GetValueOrDefault(), contoAddebito, sottoContoAddebito, parametriMovimento.Descrizione); testataMovimentiCondominiali.EsercizioRipartoContatoreCondominiale = esercizio; esercizio.TestateContabiliRipartoContatoreCondominiale.Add(testataMovimentiCondominiali); // salvo i parametri di riparto del contatore condominiale var parametriRipartoContatore = _daoFactory.GetTestataRipartoContatoreCondominialeDao() .GetByEsercizioContatore(esercizio.ID, importiDTO.Id); foreach (var ripartoContatoreCondominiale in parametriRipartoContatore) _daoFactory.GetTestataRipartoContatoreCondominialeDao() .Delete(ripartoContatoreCondominiale); var testataRipartoContatoreCondominiale = new TestataRipartoContatoreCondominiale(esercizio, _daoFactory.GetContatoreDao().GetById(importiDTO.Id*-1, false), contoAddebito, sottoContoAddebito, parametriMovimento.Descrizione); _daoFactory.GetTestataRipartoContatoreCondominialeDao().SaveOrUpdate(testataRipartoContatoreCondominiale); } } else { if (spesePresenti) { var messageSpese = spese.Aggregate(string.Empty, (current, spesa) => current + (string.Format(" - n.{0} del {1} - utenza:{2}", spesa.NumeroDocumento, spesa.DataDocumento.GetValueOrDefault().ToShortDateString(), spesa.Utenza.Numero) + Environment.NewLine)); fatalMessage += "Non sono presenti letture sufficienti per ripartire le seguenti bollette:" + Environment.NewLine + messageSpese; } else { warnMessage += string.Format("Per l'utenza: '{0}' non sono presenti bollette da ripartire", utenza.Descrizione.Trim()); } } } return new AuthorizationMessages(fatalMessage, warnMessage); } catch (Exception ex) { _log.Error("Errore inaspettato durante la ripartizione delle bollette - " + Library.Utility.GetMethodDescription() + " - idEsercizio: " + idEsercizio + " - tipoUtenza: " + tipoUtenza + " - idContoAcquaRiscaldata:" + idContoAcquaRiscaldata.GetValueOrDefault() + " - idContoRiscaldamento:" + idContoRiscaldamento.GetValueOrDefault() + " - idContoMillesimiSpalo:" + idContoMillesimiSpalo.GetValueOrDefault() + " - descrizioneMovimentoAcqua:" + descrizioneMovimentoAcqua + " - descrizioneMovimentoRiscaldamento:" + descrizioneMovimentoRiscaldamento + " - tariffaRiscaldamentoAcqua:" + tariffaRiscaldamentoAcqua + " - dataRegistrazione:" + dataRegistrazione, ex); throw; } }
public virtual object Clone() { var testata = new TestataRipartoBollette(Esercizio, TipoUtenza, DataRegistrazione); return testata; }