Skip to content

Commit

Permalink
updated range.component.showSelectedOption() to use solutionset.servi…
Browse files Browse the repository at this point in the history
…ce to create messages re selected option
  • Loading branch information
Mike Piper authored and Mike Piper committed May 19, 2020
1 parent b47b51e commit 5f6b522
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/app/data model classes/claimDates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ let minimumEndSuspensionDate: MonthYearDate = new MonthYearDate(1950, 1);

export class ClaimDates {
//This class stores information about claims for a person or a couple
//Takes one or more person objects in the constructor, pulls the relevant dates off that/those object(s), and saves the dates as fields on this object
//Then we can reference this single object as a collection of filing dates later

personARetirementDate: MonthYearDate;
personASpousalDate: MonthYearDate;
Expand Down
2 changes: 1 addition & 1 deletion src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ <h2>Recommended Strategy</h2>
<p><strong>The present value of this proposed solution would be {{this.solutionSet.solutionPV.toLocaleString('en-US', {style: 'currency', currency: 'USD', minimumFractionDigits:0, maximumFractionDigits:0})}}</strong>.</p>
<p> This means that with this strategy you could expect to receive, on average, {{this.solutionSet.solutionPV.toLocaleString('en-US', {style: 'currency',currency: 'USD', minimumFractionDigits:0, maximumFractionDigits:0})}} of total Social Security benefits over the course of your lifetime, after adjusting for the fact that a dollar received in the future is worth less than a dollar received today (because the sooner you receive a dollar the sooner you can invest it).
<a href="https://obliviousinvestor.com/what-does-present-value-mean/" target="_blank">See this article</a> for a more thorough explanation of the "present value" concept.</p>
<app-range [scenario]="scenario" [personA]="personA" [personB]="personB" [homeSetCustomDates]="setCustomDates"></app-range>
<app-range [scenario]="scenario" [recommendedSolutionSet]="solutionSet" [personA]="personA" [personB]="personB" [homeSetCustomDates]="setCustomDates"></app-range>
<app-output-table [scenario]="scenario" [personA]="personA" [personB]="personB"></app-output-table>

<!--End Recommended Strategy Output-->
Expand Down
4 changes: 2 additions & 2 deletions src/app/presentvalue.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ maximizeCouplePViterateOnePerson(scenario:CalculationScenario, flexibleSpouse:Pe
// scenario.range = new Range(flexibleSpouse.retirementBenefitDate, flexibleSpouse.retirementBenefitDate, flexibleSpouse.retirementBenefitDate, endTestDate);
scenario.range = new Range(flexibleSpouse.retirementBenefitDate, endTestDate);
// store data for the initial combination of claim dates
scenario.range.processPVs(scenario.pvNoCut, savedPV, new ClaimDates(flexibleSpouse));
scenario.range.processPVs(scenario.pvNoCut, savedPV, new ClaimDates(flexibleSpouse, fixedSpouse));

while (flexibleSpouse.retirementBenefitDate <= endTestDate && flexibleSpouse.endSuspensionDate <= endTestDate) {
//Calculate PV using current test dates for flexibleSpouse and fixed dates for fixedSpouse
Expand All @@ -808,7 +808,7 @@ maximizeCouplePViterateOnePerson(scenario:CalculationScenario, flexibleSpouse:Pe
}

// store data for this combination of claim dates
scenario.range.processPVs(scenario.pvNoCut, currentTestPV, new ClaimDates(flexibleSpouse));
scenario.range.processPVs(scenario.pvNoCut, currentTestPV, new ClaimDates(flexibleSpouse, fixedSpouse));

//If PV is greater than or equal to saved PV, save new PV and save new testDates
if (currentTestPV >= savedPV) {
Expand Down
22 changes: 15 additions & 7 deletions src/app/range/range.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,31 @@ <h2>Range of Options</h2>
<label for="showNoCut">If no cut</label>
</form>
-->
<div class="left" style="max-width:900">
<div class="left" style="max-width:900">
<canvas #canvas0 id="canvas0" title="Percent of Maximum canvas" (click)="selectCell($event, 0)" (mousemove)="update($event, 0)"
(mouseenter)="startUpdating()" (mouseleave)="stopUpdating()" style="margin-right:20px">
</canvas>
</div>

<p>This color-coded graph shows the desirability of various alternative claiming dates.
For instance, the dark green range includes filing dates that would provide an expected present value of at least 99% of that of the recommended strategy.
</p>
<p *ngIf="selectedRow < 0">Click any spot on the graph to see how the selected alternative compares to the recommended filing date(s).</p>
<p *ngIf="scenario.restrictedApplicationPossible">NOTE: Spousal benefit may be claimed before retirement benefit.</p>
<span *ngIf="selectedRow < 0">
<p>This color-coded graph shows the desirability of various alternative claiming dates.
For instance, the dark green range includes filing dates that would provide an expected present value of at least 99% of that of the recommended strategy.
</p>
<p>Click any spot on the graph to see how the selected alternative compares to the recommended filing date(s).</p>
</span>
<p *ngIf="scenario.restrictedApplicationPossible">NOTE: A restricted application (i.e., an application for just spousal benefits) will be assumed, whenever it is available given the retirement filing dates selected.</p>
<span *ngIf="selectedRow >= 0">
<p style="font-weight:bold">Selected Option: </p>
<ul>
<!-- TODO: revise below IF CLAIM DATES ARE DIFFERENT FOR CUT AND NO_CUT CASES -->
<li>{{this.selectedClaimDatesString}}</li>
<!-- Commenting these two lines out for now, since they are tenatively replaced by output below
<li>{{this.selectedClaimDatesString}}</li>
<li>{{this.selectedPercentString}}</li>
-->
<li *ngFor="let claimingSolution of this.solutionSet.solutionsArray">{{claimingSolution.message}}</li>
<li>The present value of the strategy you selected is {{this.selectedStrategyPV.toLocaleString('en-US', {style: 'currency',currency: 'USD', minimumFractionDigits:0, maximumFractionDigits:0})}}.</li>
<li>That is a difference of {{this.differenceInPV.toLocaleString('en-US', {style: 'currency',currency: 'USD', minimumFractionDigits:0, maximumFractionDigits:0})}}
({{this.differenceInPV_asPercent.toLocaleString('en-US', {minimumFractionDigits:0, maximumFractionDigits:1})}}%) relative to the suggested filing strategy.</li>
</ul>
</span>

Expand Down
59 changes: 56 additions & 3 deletions src/app/range/range.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { MonthYearDate } from '../data model classes/monthyearDate'
import { Person } from '../data model classes/person'
import { Range } from '../data model classes/range'
import { ClaimDates } from '../data model classes/claimDates'
import { SolutionSet } from '../data model classes/solutionset'
import { SolutionSetService } from '../solutionset.service'
import { BirthdayService } from '../birthday.service'

/*
This component provides a means of graphically displaying the quality of
Expand All @@ -16,6 +19,7 @@ claiming strategy, and they can select a specific strategy for further informati
// convenience constants to avoid references to a different class
const NO_CUT = Range.NO_CUT
const CUT = Range.CUT
const today:MonthYearDate = new MonthYearDate()

@Component({
selector: 'app-range',
Expand All @@ -31,6 +35,7 @@ export class RangeComponent implements OnInit, AfterViewInit {
@ViewChild('canvas0') canvasRef: ElementRef;

@Input() scenario: CalculationScenario
@Input() recommendedSolutionSet: SolutionSet
@Input() personA: Person
@Input() personB: Person
@Input() homeSetCustomDates: Function
Expand Down Expand Up @@ -127,7 +132,18 @@ export class RangeComponent implements OnInit, AfterViewInit {
selectedColor = 'black'; // mark of selected cell
pointerColor = 'rgb(250, 250, 20)'; // yellow, border around cell at pointer location

constructor() {

//solution variables
selectedStrategyPV: number
differenceInPV: number
differenceInPV_asPercent: number
solutionSet: SolutionSet = {
"solutionPV":null,
"solutionsArray": [],
"computationComplete": false
}

constructor(private solutionSetService:SolutionSetService, private birthdayService:BirthdayService) {
}

ngOnInit() {
Expand Down Expand Up @@ -427,9 +443,46 @@ showNoCut(): void {

showSelectedOption(row: number, col: number, ) {
let selectedClaimDates: ClaimDates = this.range.claimDatesArrays[this.currentCondition][row][col];
console.log("row: " + row)
console.log("col: " + col)
this.selectedClaimDatesString = selectedClaimDates.benefitDatesString();
//have to set retirementBenefitDate, spousal date, begin/endSuspensionDates on person objects if going to use functions from solutionset.service to generate solution sets
//Note that here we're pulling those dates from a ClaimDates object, which saved them from the person object(s) during the maximize PV function.
//And now we're setting those fields on the person objects back to those saved dates, so we can use solutionset.service's functions
this.personA.retirementBenefitDate = new MonthYearDate(selectedClaimDates.personARetirementDate)
this.personA.beginSuspensionDate = new MonthYearDate(selectedClaimDates.personABeginSuspensionDate)
this.personA.endSuspensionDate = new MonthYearDate(selectedClaimDates.personAEndSuspensionDate)
this.personA.spousalBenefitDate = new MonthYearDate(selectedClaimDates.personASpousalDate)
this.personB.retirementBenefitDate = new MonthYearDate(selectedClaimDates.personBRetirementDate)
this.personB.beginSuspensionDate = new MonthYearDate(selectedClaimDates.personBBeginSuspensionDate)
this.personB.endSuspensionDate = new MonthYearDate(selectedClaimDates.personBEndSuspensionDate)
this.personB.spousalBenefitDate = new MonthYearDate(selectedClaimDates.personBSpousalDate)

if (this.scenario.maritalStatus == "single"){
this.solutionSet = this.solutionSetService.generateSingleSolutionSet(this.scenario, this.personA, this.range.pvArrays[this.currentCondition][row][col])
}
else if (this.scenario.maritalStatus == "married"){
//If one spouse is already age 70, the ClaimDates object has that spouse's dates as personB dates ("because they're fixedSpouse from maximize function"), regardless of which person it was.
//So we have to swap them if it was actually personA who was over 70.
if (this.birthdayService.findAgeOnDate(this.personA, today) > 70 ){
this.personB.retirementBenefitDate = new MonthYearDate(selectedClaimDates.personARetirementDate)
this.personB.beginSuspensionDate = new MonthYearDate(selectedClaimDates.personABeginSuspensionDate)
this.personB.endSuspensionDate = new MonthYearDate(selectedClaimDates.personAEndSuspensionDate)
this.personB.spousalBenefitDate = new MonthYearDate(selectedClaimDates.personASpousalDate)
this.personA.retirementBenefitDate = new MonthYearDate(selectedClaimDates.personBRetirementDate)
this.personA.beginSuspensionDate = new MonthYearDate(selectedClaimDates.personBBeginSuspensionDate)
this.personA.endSuspensionDate = new MonthYearDate(selectedClaimDates.personBEndSuspensionDate)
this.personA.spousalBenefitDate = new MonthYearDate(selectedClaimDates.personBSpousalDate)
}
this.solutionSet = this.solutionSetService.generateCoupleSolutionSet(this.scenario, this.personA, this.personB, this.range.pvArrays[this.currentCondition][row][col])
}
else if (this.scenario.maritalStatus == "divorced"){
this.solutionSet = this.solutionSetService.generateCoupleSolutionSet(this.scenario, this.personA, this.personB, this.range.pvArrays[this.currentCondition][row][col])
}

this.selectedStrategyPV = this.range.pvArrays[this.currentCondition][row][col]
this.differenceInPV = this.recommendedSolutionSet.solutionPV - this.selectedStrategyPV
this.differenceInPV_asPercent = (1 - (this.selectedStrategyPV / this.recommendedSolutionSet.solutionPV)) * 100


let expectedPvPercent: string = this.fractionToPercent(this.range.getPvFraction(this.currentCondition, row, col), 1);
// this.pctSelStr = "Expected PV = $" + expectedPvStr + ", " + expectedPvPct + "% of max. PV";
this.selectedPercentString = "Expected PV = " + expectedPvPercent + "% of maximum PV";
Expand Down
1 change: 0 additions & 1 deletion src/app/solutionset.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export class SolutionSetService {
return solutionSet
}

//For two-person scenarios, other than a) divorce or b) one person being over 70
//In this method first we create all the possible solution objects, but then only push the ones we want into the solutionsArray.
//For example if personB can't actually qualify for spousal benefits at any time, we don't push personBspousalSolution
generateCoupleSolutionSet(scenario:CalculationScenario, personA:Person, personB:Person, savedPV: number){
Expand Down

0 comments on commit 5f6b522

Please sign in to comment.