****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: ms_episoderec.sas  
*
* Created (mm/dd/yyyy): 11/28/2012 
* Last modified: 11/28/2012 
* Version: 1.0
*
*--------------------------------------------------------------------------------------------------
* PURPOSE:
*   While allowing a maximum gap in enrollment, this program bridges member raw enrollment episodes   
*   into continuous periods.                                       
*   
*  Program inputs:                                                                                   
* 	-SAS data file with enrollment data
* 
*  Program outputs:                                                                                                                                       
* 	-SAS data file (.SAS7BDAT format) containing the bridged enrollment episodes
* 
*  PARAMETERS:                                                                       
*	-INFILE    = SAS dataset containing the raw enrollment data               						   			
*	-OUTFILE   = SAS output dataset containing the conciliated enrollment periods					   
*  	-MEDCOV    = Medical coverage indicator														       
*  	-DRUGCOV   = Drug coverage indicator															       		
*  	-ENRSTART  = Name of enrollment episode start date variable in INFILE	    					   
*  	-ENREND    = Name of enrollment episode end date variable in INFILE								   
*  	-ENROLGAP  = Maximum allowable enrollment episode gap											   
*   -REMOVEDUP = Indicates the removal of duplicates from the output file    
* 
*  Programming Notes:                                                                                
* 	-Consolidated enrollment episode start and end dates are named EStart EEnd.         
*   -User can use rename after if other names are preferred.                            
*   -In the case where there is the presence of time varying variables,                 
*    this procedure will keep all records of the input file.                            
*	-The input file must have the MEDCOV and DRUGCOV variables.                                                                          
*
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Mini-Sentinel Coordinating Center
*  info@mini-sentinel.org
*
*--------------------------------------------------------------------------------------------------
*  CHANGE LOG: 
*
*   Version   Date       Initials      Comment (reference external documentation when available)
*   -------   --------   --------   ---------------------------------------------------------------
*             mm/dd/yy
*
***************************************************************************************************;


%macro MS_EPISODEREC(INFILE=,OUTFILE=,MEDCOV=,DRUGCOV=,ENRSTART=,ENREND=,ENROLGAP=,REMOVEDUP=);

%put =====> MACRO CALLED: MS_EPISODEREC v1.0;

	%let medcovcond=1;
	%let drugcovcond=1;

	%if %eval((%upcase(&MEDCOV.) eq N or %upcase(&MEDCOV.) eq NO) and 
			  (%upcase(&DRUGCOV.) eq N or %upcase(&DRUGCOV.) eq NO))=0 %then %do;
		%if (%upcase(&MEDCOV.) eq Y or %upcase(&MEDCOV.) eq YES) %then %let medcovcond = upcase(MedCov)='Y';
		%if (%upcase(&MEDCOV.) eq N or %upcase(&MEDCOV.) eq NO) %then %let medcovcond = upcase(MedCov)='N';
		
		%if (%upcase(&DRUGCOV.) eq Y or %upcase(&DRUGCOV.) eq YES) %then %let drugcovcond = upcase(DrugCov)='Y';
		%if (%upcase(&DRUGCOV.) eq N or %upcase(&DRUGCOV.) eq NO) %then %let drugcovcond = upcase(DrugCov)='N';
	%end;

	*Determine if already sorted by PatId Enr_Start and Enr_End;
	%global SORTED;
                  
	%let RESORT=; 
	ods output attributes=attributes;
	proc contents data=&INFILE.;
	run;

	data _null_ ;
	set attributes;
	where label2=:"Sorted";
	call symput('SORTED',cvalue2);
	run;
	%put &SORTED.;

	%if &SORTED.=YES %then %do;
	
		ods output sortedby=sortedby;
		proc contents data=&INFILE.;
		run;

		data _null_;
		set sortedby;
		where label1=:"Sortedby";
		call symput('SORTEDBY',cvalue1);
		run;
		%put &SORTEDBY.;

		data _null_;
		length resort $3.;
		var=strip(compbl(upcase("&SORTEDBY.")));
		var2=strip(compbl(upcase("PatId &ENRSTART. &ENREND.")));
		if var=var2 then resort="NO";
		else resort="YES";
		call symput ('RESORT',resort);
		run;
		%put RESORT=&RESORT.;

	%end;

	%if &SORTED.=NO or &RESORT.=YES %then %let SORT_AGAIN=YES;
	%else %let SORT_AGAIN=NO;

	*if not sorted then sort otherwise do not sort;
	%if &SORT_AGAIN.=YES %then %do;
	    proc sql noprint;
        create table _denomint_ as
        Select *
        from &INFILE.(where=(&medcovcond. and &drugcovcond.))
        order by PatId, &ENRSTART., &ENREND.;
        quit;

	%end;
	%else %do;
	    data _denomint_;
		set &INFILE.(where=(&medcovcond. and &drugcovcond.));
		run;
	%end;

	*Create enrollment episodes;
	data _denomint_;
	set  _denomint_;
	by PatId;

	if &ENRSTART.-lag(&ENREND.)-1 > &ENROLGAP. then Enr_episode=Enr_episode+1; 
	if first.Patid then Enr_episode=1;

	retain Enr_episode;
	run;

	Proc SQL Noprint;
	Create Table &OUTFILE. as
	Select 	Enrol.*,
       		min(&ENRSTART.) as EStart format=mmddyy10.,
	  		max(&ENREND.) as EEnd format=mmddyy10.
	From _denomint_ as Enrol  
	group by Patid, Enr_episode;
	quit;

	*Duplicate removal if required;
	%if (%upcase(&REMOVEDUP.) eq Y or %upcase(&REMOVEDUP.) eq YES) %then %do;
		proc sort data=&OUTFILE. out=&OUTFILE.(drop=&ENRSTART. &ENREND.) NODUPKEY;
    	by PatId MEDCOV DRUGCOV EStart EEnd;
		run;
	%end;

	proc datasets library = work Nodetails nolist nowarn;
	delete _denomint_ attributes;
	quit;

	%put _LOCAL_;

%put NOTE: ******** END OF MACRO: MS_EPISODEREC v1.0 ********;

%mend MS_EPISODEREC;