/* Social Security Benefit Function for United States -
Based on Social Security Handbook 2004
---------------------------------------------------- */

program define SsBenefit_keepvar,
	syntax varlist [if], gen(namelist)
	marksample touse
	tokenize `varlist'
	#delimit;

	tempvar drop _all;

	tempvar raime saime rq sq ry_earn sy_earn;
	tempvar rclyr sclyr rbyr sbyr rmar rl sl yr;

	///1. Assign Data to Variables -------------------

	qui gen `raime'    = `1'  if `touse';
	qui gen `rq'	 = `2'  if `touse';
	qui gen `ry_earn'  = `3'  if `touse';
	qui gen `rclyr'    = `4'  if `touse';
	qui gen `rbyr'     = `5'  if `touse';
	qui gen `rl'       = `6'  if `touse';
	qui gen `saime'    = `7'  if `touse';
	qui gen `sq'       = `8'  if `touse';
	qui gen `sy_earn'  = `9'  if `touse';
	qui gen `sclyr'    = `10' if `touse';
	qui gen `sbyr'     = `11' if `touse';
	qui gen `sl'       = `12' if `touse';
	qui gen `rmar'     = `13' if `touse';
	qui gen `yr'       = `14' if `touse';

	/// 2.A Important Indicators ----------------------
	tempvar ry60 sy60 ry62 sy62 rynra synra ry70 sy70 rage sage;

	  qui gen `ry60' = `rbyr' + 60 if `touse';
 	  qui gen `ry62' = `rbyr' + 62 if `touse';
	  qui gen `ry70' = `rbyr' + 70 if `touse';
	  qui egen `rynra' = nra(`rbyr') if `touse';
  	  qui replace `rynra' = `rbyr' + `rynra' if `touse';

	  qui gen `sy60' = `sbyr' + 60 if `touse';
	  qui gen `sy62' = `sbyr' + 62 if `touse';
	  qui gen `sy70' = `sbyr' + 70 if `touse';
	  qui egen `synra' = nra(`sbyr') if `touse';
  	  qui replace `synra' = `sbyr' + `synra' if `touse';


	  qui gen `rage' = `yr' - `rbyr' if `touse';
	  qui gen `sage' = `yr' - `sbyr' if `touse';


	/// Determine Eligibility based on age and quarters or coverage
	tempvar rmin smin re se;
	qui gen `rmin' = 40 if `touse';
	qui replace `rmin' = 40 - (1929-`rbyr') if `rbyr'<1929&`touse';
	qui gen `smin' = 40 if `touse';
	qui replace `smin' = 40 - (1929-`sbyr') if `sbyr'<1929&`touse';

	qui gen `re' = (`rage'>=62)&(`rq'>=`rmin') if `touse'&`sl'==1;
	qui replace `re' = (`rage'>=60)&(`rq'>=`rmin') if `touse'&`sl'==0;
	qui gen `se' = (`sage'>=62)&(`sq'>=`smin') if `touse'&`rl'==1;
	qui replace `se' = (`sage'>=60)&(`sq'>=`smin') if `touse'&`rl'==0;

	/// Get PIA based on AIME, quarters (for minimum PIA) and birth year
	tempvar rpia spia;
	SsPIA_keepvar `raime' `rq' `rbyr' if `touse', gen(`rpia');
	foreach x in y60 nwi60 bend1 bend2 {;
		ren `x' `x'_r;
	};

	SsPIA_keepvar `saime' `sq' `sbyr' if `touse', gen(`spia');

	/// Get DRC or ARF based on birth year and claiming date
	tempname arf;
	tempvar rdrc sdrc rr sr;
	scalar `arf' = 0.0678;
	qui egen `rdrc' = drc(`rbyr') if `touse';
	qui egen `sdrc' = drc(`sbyr') if `touse';

	qui replace `rdrc' = exp(`arf'*max(min(`rclyr'-`rynra',0),62-`rynra')) if `rclyr'<=`rynra'&`touse';
	qui replace `rdrc' = exp(`rdrc'*min(`rclyr'-`rynra',`ry70'-`rynra')) if `rclyr'>`rynra'&`touse';

	qui replace `sdrc' = exp(`arf'*max(min(`sclyr'-`synra',0),62-`synra')) if `sclyr'<=`synra'&`touse';
	qui replace `sdrc' = exp(`sdrc'*min(`sclyr'-`synra',`sy70'-`synra')) if `sclyr'>`synra'&`touse';
	qui gen `rr' = `rclyr'<=`yr' if `touse';
	qui gen `sr' = `sclyr'<=`yr' if `touse';
	qui replace `rdrc' = 0 if (`rl'==0|`rr'==0|`re'==0)&`touse';
	qui replace `sdrc' = 0 if (`sl'==0|`sr'==0|`se'==0)&`touse';
	/// Calculate Admissible Benefits on own account
	tempvar rben_g sben_g;
	qui gen `rben_g' = `rdrc'*`rpia' if `touse';
	qui gen `sben_g' = `sdrc'*`spia' if `touse';

	/// Calculate Benefit admissible as spouse
	tempvar rben_s sben_s;
	tempname sp_factor;
	scalar `sp_factor' = 0.5;
	qui gen `rben_s' = max(`sp_factor'*`rdrc'*`spia' - `rben_g',0) if `touse';
	qui replace `rben_s' = 0 if `sr'==0&`touse';

	qui gen `sben_s' = max(`sp_factor'*`sdrc'*`rpia' - `sben_g',0) if `touse';
	qui replace `sben_s' = 0 if `rr'==0&`touse';

	/// If not married, no spousal benefits
	qui replace `rben_s' = 0 if `rmar'==0&`touse';
	qui replace `sben_s' = 0 if `rmar'==0&`touse';

	/// Survivor Benefits
	tempvar rben_v sben_v;
	qui gen `rben_v' = 0;
	qui gen `sben_v' = 0;
	qui replace `rben_v' = max(`rdrc'*`spia' - `rben_g',0) if `sl'==0&`touse';
	qui replace `sben_v' = max(`sdrc'*`rpia' - `sben_g',0) if `rl'==0&`touse';

	/// If married, no survival benefits
	qui replace `rben_v' = 0 if `rmar'==1 &`touse';
	qui replace `sben_v' = 0 if `rmar'==1 &`touse';

	foreach x in rben_g rben_s rben_v {;
		gen `x'_old = ``x'';
	};

	/// Calculate Total Benefit for Purpose of Earnings Test
	tempvar rben_all sben_all;
	qui gen `rben_all' = `rben_g' + `rben_s' + `rben_v' if `touse';
  	qui gen `sben_all' = `sben_g' + `sben_s' + `sben_v' if `touse';
///	sum `re' `rpia' `rdrc' `rben_g' `rben_all' `se' `spia' `sdrc' `sben_g' `sben_all';


	/// Get Earnings Disregard
	tempvar rea_cap sea_cap;
	qui egen `rea_cap' =  eadisreg(`yr' `rage') if `touse';
	qui egen `sea_cap' =  eadisreg(`yr' `sage') if `touse';

	/// Appl Tax Rates to Earnings Over Cap
	tempname ea_era ea_nra;
	scalar `ea_era' = 1/2;
  	scalar `ea_nra' = 1/3;
	tempvar rea_tax sea_tax;
	qui gen `rea_tax' = `ea_era'*max(`ry_earn'-`rea_cap',0) if `touse'&`yr'<`rynra';
	qui replace `rea_tax' = `ea_nra'*max(`ry_earn'-`rea_cap',0) if `touse'&`yr'>=`rynra';
	qui replace `rea_tax' = 0 if `touse'&`rea_tax'==.;
	qui gen `sea_tax' = `ea_era'*max(`sy_earn'-`sea_cap',0) if `touse'&`yr'<`synra';
	qui replace `sea_tax' = `ea_nra'*max(`sy_earn'-`sea_cap',0) if `touse'&`yr'>=`synra';
	qui replace `sea_tax' = 0 if `touse'&`sea_tax'==.;

	qui replace `rea_tax' = max(min(`rea_tax'/`rben_all',1),0) if `touse'&`rben_all'!=0;
	qui replace `sea_tax' = max(min(`sea_tax'/`sben_all',1),0) if `touse'&`sben_all'!=0;

	// Proportional Reduction of All benefits
	qui replace `rben_g' = `rben_g'*(1-`rea_tax') if `rea_tax'!=.&`touse';
	qui replace `rben_s' = `rben_s'*(1-`rea_tax') if `rea_tax'!=.&`touse';
	qui replace `rben_v' = `rben_v'*(1-`rea_tax') if `rea_tax'!=.&`touse';

	// Proportional Reduction of All benefits
	qui replace `sben_g' = `sben_g'*(1-`sea_tax') if `sea_tax'!=.&`touse';
	qui replace `sben_s' = `sben_s'*(1-`sea_tax') if `sea_tax'!=.&`touse';
	qui replace `sben_v' = `sben_v'*(1-`sea_tax') if `sea_tax'!=.&`touse';

	/// Sep 14, 2008 - adjust to 2004 dollars ;
	tempvar cola_r60 cola_s60 cola_04 ;
	qui egen `cola_r60' = cola(`ry60');
	qui egen `cola_s60' = cola(`sy60');
	qui egen `cola_04'  = cola(2004);

	foreach x in rben_g rben_s rben_v {;
		qui replace ``x'' = ``x''* (`cola_04'/`cola_r60') if `touse' & !missing(``x'');
	};

	foreach x in sben_g sben_s sben_v {;
		qui replace ``x'' = ``x''* (`cola_04'/`cola_s60') if `touse' & !missing(``x'');
	};

	tokenize `gen';
	qui gen `1' = `rben_g' if `touse';
	qui gen `2' = `rben_s' if `touse';
	qui gen `3' = `rben_v' if `touse';
	qui gen `4' = `sben_g' if `touse';
	qui gen `5' = `sben_s' if `touse';
	qui gen `6' = `sben_v' if `touse';


	* Keep temperary variables;
	foreach x in ry60 sy60 ry62 sy62 rynra synra ry70 sy70
	rmin smin re se rpia spia rdrc sdrc rr
	sr sp_factor ea_era ea_nra rea_cap sea_cap rea_tax sea_tax rben_all sben_all {;
		noi dis "`x'" ;
		gen `x' = ``x'';
	};


end;