public static void PrintPayments(IEnumerable <MonthPayment> monthPayments, bool withPaymentsDetails = false) { MonthPayment prev = null; bool todayPrined = false; decimal totalInterest = 0; decimal totalPaid = 0; decimal totalInvest = 0; decimal totalInvestGrn = 0; int mI = 1; int pI = 1; foreach (var m in monthPayments) { decimal body = prev != null ? m.Paid - prev.Interest : 0; decimal interest = prev != null ? prev.Interest : 0; decimal debt = m.Debt - body; if (m.Date > DateTime.Today && todayPrined == false) { Trace.WriteLine(""); Trace.WriteLine("For today:"); Trace.WriteLine("----------"); Trace.WriteLine(string.Format( "Total paid:\t\t{0,12:0.00}\nTotal body:\t\t{1,12:0.00}\nTotal interest:\t{2,12:0.00}\nTotal invest:\t{3,12:0.00} usd = {4:0.00} uah", totalPaid, totalPaid - totalInterest, totalInterest, totalInvest, totalInvestGrn)); Trace.WriteLine(""); todayPrined = true; } totalInterest += interest; totalPaid += m.Paid; totalInvest += m.Invest; totalInvestGrn += m.InvestGrn; string investStr = m.Invest != 0 ? string.Format("invest: {0:0.00} usd, {1:0.00} uah", m.Invest, m.InvestGrn) : ""; Trace.WriteLine( string.Format( "{0,2} {1,15:MMMM yyyy} {2,12:0.00} {3,9:0.00} {4,9:0.00} {5,9:0.00} {6} {7}", mI++, m.Date, debt, interest, body, m.Paid, m.InvalidCalculation ? "+" : "", investStr)); if (withPaymentsDetails && m.Payments != null) { foreach (var p in m.Payments) { Trace.WriteLine(string.Format("\t\t\t\t\t\t\t{0} {1,15:dd/MM/yyyy} {2,12:0.00} {3}", pI++, p.PaymentDate, p.PayAmount, PrintInvest(p))); } } prev = m; } Trace.WriteLine(""); Trace.WriteLine(string.Format( "Total paid:\t\t{0,12:0.00}\nTotal body:\t\t{1,12:0.00}\nTotal interest:\t{2,12:0.00}\nTotal invest:\t{3,12:0.00} usd = {4:0.00} uah", totalPaid, totalPaid - totalInterest, totalInterest, totalInvest, totalInvestGrn)); }
/// <summary> /// Calculate mothly payments /// </summary> /// <param name="payments">payments array</param> /// <param name="startDate">first payment date</param> /// <param name="debtAmount">debt amount</param> /// <param name="withInvest">true - use ivestments during calculation, false - calculate without investments</param> /// <returns></returns> public MonthPayment[] Calculate(Payment[] payments, DateTime startDate, decimal debtAmount, bool withInvest = true) { var firstDay = startDate; const decimal interestPerHour = 12.7m / (24 * 360 * 100); decimal debt = debtAmount; var list = new List <MonthPayment>(); int i = 0; MonthPayment prevM = null; while (debt > 0 && i < payments.Length) { var m = new MonthPayment(); list.Add(m); m.Debt = debt; m.Date = firstDay; DateTime nextMonth = new DateTime(firstDay.Year, firstDay.Month, 1).AddMonths(1); if (payments[i].PaymentDate > nextMonth) { m.Interest = debt * interestPerHour * (decimal)(nextMonth - firstDay).TotalHours; firstDay = nextMonth; prevM = m; continue; } int j = 0; var paymentsList = new List <Payment>(); decimal prevInterest = prevM != null ? prevM.Interest : 0; decimal invetstMultyplier = withInvest ? 1 : 0; while (i < payments.Length && payments[i].PaymentDate < nextMonth) { if (payments[i].Interest != null && prevM != null && Math.Abs(prevM.Difference = (payments[i].Interest.Value - prevM.Interest)) > 0.006m && prevM.InvalidCalculation == false) { prevM.InvalidCalculation = true; } paymentsList.Add(payments[i].Clone()); DateTime beginDate = j == 0 ? firstDay : payments[i - 1].PaymentDateWithShift; m.Interest += debt * interestPerHour * (decimal)(payments[i].PaymentDateWithShift - beginDate).TotalHours; m.Invest += payments[i].Invest * invetstMultyplier; m.InvestGrn += payments[i].InvestGrn * invetstMultyplier; decimal invest = payments[i].Invest * (invetstMultyplier); decimal payAmount = payments[i].PayAmount + (invest > 0 ? invest : 0); if (payAmount >= prevInterest) { debt -= (payAmount - prevInterest); prevInterest = 0; } else { prevInterest -= payAmount; } m.Paid += payAmount; i++; j++; } m.Payments = paymentsList.ToArray(); m.Interest += debt * interestPerHour * (decimal)(nextMonth - payments[i - 1].PaymentDateWithShift).TotalHours; firstDay = nextMonth; prevM = m; } return(list.ToArray()); }