public string DeleteDettaglioPianoRateale(PianoRatealeDettaglioDTO rata) { var result = GetServiceClient().DeleteDettaglioPianoRateale(rata.ID, GetUserInfo()); CloseService(); return result; }
public PianoRatealeDTO CreatePianoRateale(PianoRatealeDTO testataPianoRateale, int numeroRate, IList<RiepilogoRipartoDTO> riepilogoRiparto) { var esercizio =_daoFactory.GetEsercizioDao().GetById(testataPianoRateale.IdEsercizio, false); var impostazioni = _daoFactory.GetImpostazioniAziendaDao().GetByAzienda(esercizio.CondominioRiferimento.Azienda.ID); var arrotondamenti = new Dictionary<int, decimal>(); var rendiconto = _daoFactory.GetRendicontoAnnualeDao().Find(testataPianoRateale.IdRendiconto.GetValueOrDefault(), false) ?? _bilancioService.GetPreventivoCorrente(testataPianoRateale.IdEsercizio); testataPianoRateale.IdRendiconto = rendiconto.ID; // Se non è stato definito nessun arrotondamento, arrotondo comunque a .01 var arrotondamentoImporti = 0.01m; if (testataPianoRateale.ArrontondamentoImporti > 0) arrotondamentoImporti = testataPianoRateale.ArrontondamentoImporti; // -------------------------------------------------------------------- // Leggo eventuali rate di acconto presenti // -------------------------------------------------------------------- var pianoAcconto = _daoFactory.GetPianoRatealeDao().GetByEsercizio(esercizio); IList<PianoRatealeDettaglio> listaDettaglioPianoAcconto = null; if (pianoAcconto != null) { testataPianoRateale.ID = pianoAcconto.ID; listaDettaglioPianoAcconto = (pianoAcconto.Rate.Where(item => item.IsAcconto)).ToList(); } // -------------------------------------------------------------------- // Creazione Piano Rateale // -------------------------------------------------------------------- var startIndex = 1; var numeroRateAcconto = 0; DateTime? dataIniziale = null; if (listaDettaglioPianoAcconto != null) { startIndex = listaDettaglioPianoAcconto.Count + 1; numeroRateAcconto = listaDettaglioPianoAcconto.Count(item => item.IsAcconto); var ultimaRata = listaDettaglioPianoAcconto.OrderBy(item => item.DataScadenza).LastOrDefault(); if (ultimaRata?.DataScadenza != null) dataIniziale = ultimaRata.DataScadenza.GetValueOrDefault(); } numeroRate += numeroRateAcconto; if (testataPianoRateale.Rate == null || testataPianoRateale.Rate.Count != numeroRate) { testataPianoRateale.Rate = new List<PianoRatealeDettaglioDTO>(); // Calcolo la distanza proposto, in numero di mesi, tra una rata e quella successiva var denominatore = numeroRate - startIndex + 1; var numeroMesi = DivideRoundingUp(numeroRate, 12)*12; var monthGap = numeroMesi/12; if (dataIniziale == null && esercizio.DataApertura != null) dataIniziale = esercizio.DataApertura.GetValueOrDefault(); if (dataIniziale == null) dataIniziale = new DateTime(DateTime.Today.Year, 2, 1); if(esercizio.DataChiusura != null && esercizio.Gestione == GestioneEsercizioEnum.Ordinario && numeroMesi <= 12) numeroMesi = Convert.ToInt32(Math.Round((esercizio.DataChiusura.GetValueOrDefault() - dataIniziale.GetValueOrDefault()).TotalDays / 30)); if(denominatore > 0) monthGap = numeroMesi / denominatore; var scadenza = new DateTime(dataIniziale.GetValueOrDefault().AddMonths(1).Year, dataIniziale.GetValueOrDefault().AddMonths(1).Month, 1); var rataIndex = 0; for (var i = startIndex; i <= numeroRate; i++) { var dettaglio = new PianoRatealeDettaglioDTO {DataScadenza = scadenza, Progressivo = i}; if (i == startIndex) dettaglio.PercentualeRipartoSaldo = 1m; dettaglio.PercentualeRiparto = Math.Round(1m / Convert.ToDecimal(numeroRate - startIndex + 1), 4); rataIndex++; dettaglio.Descrizione = $"Rata n. {rataIndex} del {scadenza:d}"; scadenza = scadenza.AddMonths(monthGap); testataPianoRateale.Rate.Add(dettaglio); } } // -------------------------------------------------------------------- // Calcolo importi piano rateale // -------------------------------------------------------------------- if (riepilogoRiparto == null) riepilogoRiparto = GetRiepilogoRiparto(testataPianoRateale.IdEsercizio, null, null, testataPianoRateale.Tipo); // Se arriva dal client cambio segno agli importi. else if (impostazioni.InversioneSaldiRate) { foreach (var item in riepilogoRiparto) item.Importo = item.Importo * -1; } var importiNegativi = new Dictionary<int, decimal>(); var importiMinimi = new Dictionary<int, decimal>(); _rateCreate = new List<RataSoggettoDTO>(); foreach (var dettaglio in testataPianoRateale.Rate) { if (dettaglio.ID == 0) { dettaglio.Importo = 0; // =========================================================================== // Creazione delle rate // =========================================================================== foreach (var itemRiepilogo in riepilogoRiparto) { var idSoggettoCondominio = getSoggettoCondominioPrincipale(itemRiepilogo.IdPersona, itemRiepilogo.IdSoggettoCondominio, null, riepilogoRiparto, testataPianoRateale); RataSoggettoDTO rata; if (!_rateCreate.Any(item => item.IdSoggettoCondominio == idSoggettoCondominio && item.DataScadenza == dettaglio.DataScadenza)) { rata = new RataSoggettoDTO { IdEsercizio = esercizio.ID, DescrizioneEsercizio = esercizio.DisplayName, DataScadenza = dettaglio.DataScadenza, Progressivo = dettaglio.Progressivo, IdPianoDettaglioRatealeRiferimento = dettaglio.ID, IdSoggettoCondominio = idSoggettoCondominio, DisplayName = itemRiepilogo.Nominativo, DescrizioneUnitaImmobiliare = itemRiepilogo.DescrizioneUnitaImmobiliare, IdPersona = itemRiepilogo.IdPersona, DescrizioneSoggettoCondominio = itemRiepilogo.Nominativo, OrdineUnitaImmobiliare = itemRiepilogo.OrdineUnitaImmobiliare, TipoSoggettoCondominio = itemRiepilogo.TipoSoggettoCondominio, Subalterno = itemRiepilogo.Subalterno }; _rateCreate.Add(rata); } else { var dettaglio2 = dettaglio; rata = (from item in _rateCreate where idSoggettoCondominio == item.IdSoggettoCondominio && item.DataScadenza == dettaglio2.DataScadenza select item).SingleOrDefault(); } // =========================================================================== // Calcolo Importo // =========================================================================== // Importo preventivo // ------------------------------ var importoPreventivo = getImportoNettoAcconti(itemRiepilogo, listaDettaglioPianoAcconto) * dettaglio.PercentualeRiparto.GetValueOrDefault(); // Importo saldo // ------------------------------ var importoSaldo = itemRiepilogo.SaldoEsercizioPrecedente * dettaglio.PercentualeRipartoSaldo.GetValueOrDefault(); if (impostazioni.InversioneSaldiRate) importoSaldo = importoSaldo*-1; // Rata totale // ------------------------------ if (rata != null) { var importoRata = rata.Importo.GetValueOrDefault() + importoSaldo + importoPreventivo; rata.Importo = importoRata; } } // =========================================================================== // Rilettura delle rate la gestione degli importi minimi // =========================================================================== var dettaglio1 = dettaglio; var ratePerDettaglio = from item in _rateCreate where dettaglio1 != null && item.DataScadenza == dettaglio1.DataScadenza select item; foreach (var rata in ratePerDettaglio) { var importoRata = rata.Importo.GetValueOrDefault(); // Se presenti importi minimi devo aggiungerli alla rata if (importiNegativi.ContainsKey(rata.IdSoggettoCondominio)) { var importoNegativo = importiNegativi[rata.IdSoggettoCondominio]; importoRata += importoNegativo; importiNegativi.Remove(rata.IdSoggettoCondominio); } // Creo rata solo se importo è maggiore dell'importo minimo, se è inferiore al minimo lo memorizzo per utilizzarlo nelle rate successive if (importoRata > testataPianoRateale.ImportoMinimo) { rata.Importo = Convert.ToDecimal(Arrotonda.Round(Convert.ToDouble(importoRata), Convert.ToDouble(arrotondamentoImporti))); // memorizzo eventuali arrotondamenti decimal importoArrontondamento = 0; if (arrotondamenti.ContainsKey(rata.IdSoggettoCondominio)) { importoArrontondamento = arrotondamenti[rata.IdSoggettoCondominio]; arrotondamenti.Remove(rata.IdSoggettoCondominio); } importoArrontondamento += importoRata - rata.Importo.GetValueOrDefault(); arrotondamenti.Add(rata.IdSoggettoCondominio, importoArrontondamento); } else { rata.Importo = 0; if (importoRata < 0) { decimal importo = 0; if (importiNegativi.ContainsKey(rata.IdSoggettoCondominio)) { importo = importiNegativi[rata.IdSoggettoCondominio]; importiNegativi.Remove(rata.IdSoggettoCondominio); } importo += importoRata; importiNegativi.Add(rata.IdSoggettoCondominio, importo); } else { decimal importo = 0; if (importiMinimi.ContainsKey(rata.IdSoggettoCondominio)) { importo = importiMinimi[rata.IdSoggettoCondominio]; importiMinimi.Remove(rata.IdSoggettoCondominio); } importo += importoRata; importiMinimi.Add(rata.IdSoggettoCondominio, importo); } } // ------------------------------- // Aggiorno dettaglio rata // ------------------------------- dettaglio.Importo += rata.Importo.GetValueOrDefault(); } } } // --------------------------------------------------------------------------------- // Aggiungo le rate di acconto // --------------------------------------------------------------------------------- int index = 0; if (listaDettaglioPianoAcconto != null) { foreach (PianoRatealeDettaglio dettaglioPianoAcconto in listaDettaglioPianoAcconto) { if (testataPianoRateale.Rate.All(item => item.ID != dettaglioPianoAcconto.ID)) { index++; var dettaglioAccontoDto = new PianoRatealeDettaglioDTO { ID = dettaglioPianoAcconto.ID, IsAcconto = true, DataScadenza = dettaglioPianoAcconto.DataScadenza.GetValueOrDefault(), Descrizione = dettaglioPianoAcconto.Descrizione, IsDeleteAllow = false, IdPianoRatealeRiferimento = dettaglioPianoAcconto.PianoRatealeRiferimento.ID, StatoRata = dettaglioPianoAcconto.Stato, Version = dettaglioPianoAcconto.Version, Progressivo = index, Importo = dettaglioPianoAcconto.RateSoggetti.Where(item => !item.DaRichiamare && item.Stato != StatoRataEnum.Richiamata).Sum(item => item.Importo) }; testataPianoRateale.Rate.Add(dettaglioAccontoDto); } foreach (RataSoggetto rataAcconto in dettaglioPianoAcconto.RateSoggetti.Where(item => !item.DaRichiamare && item.Stato != StatoRataEnum.Richiamata)) { var rataAccontoDto = new RataSoggettoDTO { ID = rataAcconto.ID, DataScadenza = rataAcconto.DataScadenza, DescrizioneSoggettoCondominio = rataAcconto.Soggetto.DisplayName, DescrizioneUnitaImmobiliare = rataAcconto.Soggetto.UnitaImmobiliare.Descrizione, IdEsercizio = rataAcconto.PianoRatealeDettaglio.PianoRatealeRiferimento.Esercizio.ID, DescrizioneEsercizio = rataAcconto.PianoRatealeDettaglio.PianoRatealeRiferimento.Esercizio.DisplayName, IdPianoDettaglioRatealeRiferimento = rataAcconto.PianoRatealeDettaglio.ID, IdUnitaImmobiliare = rataAcconto.Soggetto.UnitaImmobiliare.ID, Subalterno = rataAcconto.Soggetto.UnitaImmobiliare.Subalterno, Importo = rataAcconto.Importo, ImportoPagato = rataAcconto.GetImportoVersato(null), OrdineUnitaImmobiliare = rataAcconto.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault(), StatoRata = rataAcconto.Stato, TipoSoggettoCondominio = rataAcconto.Soggetto.Tipo, Version = rataAcconto.Version, IsDeleteAllow = false, Progressivo = rataAcconto.Progressivo, IdPersona = rataAcconto.Soggetto.Persona.ID, IdSoggettoCondominio = getSoggettoCondominioPrincipale(rataAcconto.Soggetto.Persona.ID, rataAcconto.Soggetto.ID, rataAcconto.Soggetto.SoggettoPrincipale, riepilogoRiparto, testataPianoRateale) }; _rateCreate.Insert(0, rataAccontoDto); } } } testataPianoRateale.Rate = testataPianoRateale.Rate.OrderBy(item => item.Progressivo).ToList(); // --------------------------------------------------------------------------------- // Se ho ancora importi minimi li addebito alla prima rata ancora a 0 // Può capitare, ad esempio, se abbiamo definito una rata che comprende il solo saldo // --------------------------------------------------------------------------------- foreach (var kvp in importiMinimi) { var kvp1 = kvp; var ratePerImporto = from item in _rateCreate where item.IdSoggettoCondominio == kvp1.Key orderby item.Importo, item.Progressivo select item; if (ratePerImporto.Any()) { var importoArrotondato = Convert.ToDecimal(Arrotonda.Round(Convert.ToDouble(kvp.Value), Convert.ToDouble(arrotondamentoImporti))); var rata = ratePerImporto.FirstOrDefault(); if(rata != null) rata.Importo += importoArrotondato; // Aggiungo il residuo alla lista degli arrontondamenti if (kvp.Value != importoArrotondato) { if (arrotondamenti.ContainsKey(kvp.Key)) arrotondamenti[kvp.Key] += (kvp.Value - importoArrotondato); else arrotondamenti.Add(kvp.Key, kvp.Value - importoArrotondato); } } else { _log.WarnFormat("Non trovata nessun rata a cui addebitare l'importo minimo di {0} - {1} - id:{2}", kvp.Value.ToString("c"), Utility.GetMethodDescription(), kvp.Key); } } // --------------------------------------------------------------------------------- // Calcolo residui - Solo se presente rata di arrotondamento // --------------------------------------------------------------------------------- if (testataPianoRateale.IdRataArrotondamenti > 0) { decimal residuoTotale = 0; foreach (RiepilogoRipartoDTO itemRiepilogo in riepilogoRiparto) { if (arrotondamenti.ContainsKey(itemRiepilogo.IdSoggettoCondominio)) { decimal importoResiduo = arrotondamenti[itemRiepilogo.IdSoggettoCondominio]; var riepilogo = itemRiepilogo; RataSoggettoDTO rataResiduo = (from rata in _rateCreate where rata.Progressivo == testataPianoRateale.IdRataArrotondamenti && rata.IdSoggettoCondominio == riepilogo.IdSoggettoCondominio && rata.Importo > 0 select rata).SingleOrDefault(); if (rataResiduo != null) { rataResiduo.Importo += importoResiduo; residuoTotale += importoResiduo; arrotondamenti.Remove(itemRiepilogo.IdSoggettoCondominio); } } } // --------------------------------------------------------------------------------- // Se ho ancora residui di arrotondamento li addebito alla prima rata disponibile > 0 // --------------------------------------------------------------------------------- foreach (var kvp in arrotondamenti) { var importoResiduo = kvp.Value; var kvp1 = kvp; var rateResiduo = from item in _rateCreate where item.IdSoggettoCondominio == kvp1.Key && item.Importo > 0 orderby item.Progressivo select item; if (rateResiduo.Any()) { foreach (var rataResiduo in rateResiduo) { if (rataResiduo.Importo + importoResiduo >= 0) { rataResiduo.Importo += importoResiduo; residuoTotale += importoResiduo; break; } } } } // --------------------------------------------------------------------------------- // Aggiorno col residuo la rata di dettaglio // --------------------------------------------------------------------------------- var dettaglioResiduo = (from dettaglio in testataPianoRateale.Rate where dettaglio.Progressivo == testataPianoRateale.IdRataArrotondamenti select dettaglio).SingleOrDefault(); if (dettaglioResiduo != null) dettaglioResiduo.Importo += residuoTotale; } // --------------------------------------------------------------------------------- // Se ho ancora importi negativi verifico se riesco a sottrarli da qualche rata: // Può capitare, ad esempio, se abbiamo definito una rata che comprende il solo saldo // --------------------------------------------------------------------------------- var importiNegativiDaSottrarre = importiNegativi.Select(kvp => new ImportiDTO { Id = kvp.Key, Importo = kvp.Value*-1 }).ToList(); foreach (var importoDto in importiNegativiDaSottrarre) { var dto = importoDto; var rateSoggetto = from item in _rateCreate where item.IdSoggettoCondominio == dto.Id select item; foreach (var rata in rateSoggetto) { // Solo per le rate nuove if (rata.ID == 0) { decimal importoOriginale = rata.Importo.GetValueOrDefault(); if (rata.Importo >= importoDto.Importo) rata.Importo -= importoDto.Importo; else if (rata.Importo < importoDto.Importo) rata.Importo = 0; importoDto.Importo -= importoOriginale - rata.Importo.GetValueOrDefault(); } } } return testataPianoRateale; }
private PianoRatealeDTO setDto(PianoRateale item, bool dettaglioRate) { var dto = new PianoRatealeDTO { Version = item.Version, ArrontondamentoImporti = item.ArrotondamentoImporti.GetValueOrDefault(), ID = item.ID, IdEsercizio = item.Esercizio.ID, Tipo = item.Tipo }; if (item.RataArrotondamenti != null) { try { dto.IdRataArrotondamenti = item.RataArrotondamenti.ID; } catch (Exception ex) { _log.ErrorFormat("Errore nella lettura della rata di arrotondamento - {0} - pianoRateale:{1} - azienda:{2}", ex, Utility.GetMethodDescription(), item.ID, _info.Azienda); } } if(item.Rendiconto != null) dto.IdRendiconto = item.Rendiconto.ID; // Dettaglio Rate dto.Rate = new List<PianoRatealeDettaglioDTO>(item.Rate.Count); if (dettaglioRate) { foreach (var dettaglio in item.Rate.OrderBy(itemDettaglio => itemDettaglio.Progressivo)) { var dettaglioDTO = new PianoRatealeDettaglioDTO { DataScadenza = dettaglio.DataScadenza.GetValueOrDefault(), Descrizione = dettaglio.Descrizione, DisplayName = dettaglio.Descrizione, ID = dettaglio.ID, IdPianoRatealeRiferimento = item.ID, Importo = dettaglio.RateSoggetti.Sum(itemRata => itemRata.Importo), PercentualeRiparto = dettaglio.PercentualeRiparto, PercentualeRipartoSaldo = dettaglio.PercentualeSaldoEsercizioPrecedente, Progressivo = dettaglio.Progressivo, IsAcconto = dettaglio.IsAcconto, StatoRata = dettaglio.Stato }; dto.Rate.Add(dettaglioDTO); } } return dto; }