private IRetirementReport ReportFor(Family family, bool exitOnceMinCalcd = false, DateTime?givenRetirementDate = null) { _incomeTaxCalculator = new IncomeTaxCalculator(); var result = new RetirementReport(_pensionAgeCalc, _incomeTaxCalculator, family, _now, givenRetirementDate, _assumptions, _taxSystem); var calcdMinimum = false; var monthsToDeath = MonthsToDeath(family.PrimaryPerson.Dob, _now); for (var month = 1; month <= monthsToDeath; month++) { ProgressTheResultBy1Month(family, givenRetirementDate, result, calcdMinimum); if (givenRetirementDate == null && !calcdMinimum) { var retirementReport = result.CopyCalcMinimumMode(); if (IsThatEnoughTillDeath(family, retirementReport, month, monthsToDeath)) { result.Persons.ForEach((p) => p.FinancialIndependenceDate = result.PrimaryPerson.StepReport.CurrentStep.StepDate); if (exitOnceMinCalcd) { return(result); } calcdMinimum = true; } } } return(result); }
private bool IsThatEnoughTillDeath(Family family, RetirementReport report, int month, int monthsToDeath) { var emergencyFundMet = false; var minimumCash = 0; for (var m = month + 1; m <= monthsToDeath; m++) { var addMonths = _now.AddMonths(m); ProgressTheResultBy1Month(family, null, report, true); if (report.EmergencyFund() >= report.RequiredEmergencyFund(addMonths)) { emergencyFundMet = true; } if ((report.Investments() + report.EmergencyFund() <= minimumCash) || (emergencyFundMet && report.Investments() <= minimumCash)) { return(false); } } return(emergencyFundMet); }
private void ProgressTheResultBy1Month(Family family, DateTime?givenRetirementDate, RetirementReport result, bool calcdMinimum) { foreach (var person in result.Persons) { person.StepReport.NewStep(calcdMinimum, result, result.Persons.Count, givenRetirementDate); if (person.Retired(calcdMinimum, person.StepReport.CurrentStep.StepDate, givenRetirementDate)) { person.CrystallisePension(); } var salary = person.MonthlySalaryAfterDeductionsAt(person.StepReport.CurrentStep.StepDate); person.StepReport.UpdateSpending(); person.StepReport.UpdatePrivatePension(); person.StepReport.UpdateGrowth(); person.StepReport.UpdateStatePensionAmount(_statePensionAmountCalculator, person.StatePensionDate, salary); person.StepReport.UpdateSalary(salary); person.StepReport.ProcessTaxableIncomeIntoSavings(); } var personWithClaim = result.PersonReportFor(family.PersonWithChildBenefitClaim()); if (personWithClaim != null) { var personWithoutClaim = result.PersonReportFor(family.PersonWithoutChildBenefitClaim()); personWithClaim.StepReport.UpdateChildBenefit(personWithoutClaim); } result.BalanceSavings(); }