****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: ms_findgap.sas  
*
* Created (mm/dd/yyyy): 07/31/2014
* Last modified: 07/21/2019
* Version: 1.5
*
*--------------------------------------------------------------------------------------------------
* PURPOSE:
*   This program will find any first date that is the first after a user 
*   defined gap (or the very first). 
*
*  Program inputs:                                                                                   
*   -Dataset in which gaps are to be looked for 
* 
*  Program outputs:                                                                                                                                       
*   -Dataset with the gap condition applied  
* 
* PARAMETERS:
*   -InFile = Name of the dataset in which gaps are to be found
*   -OutFile= Name of the output dataset with the gap condition applied
*   -gap    = Gap value to look for between records according to gapby
*
*  Programming Notes:                                                                                
*                                                                           
*
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Sentinel Coordinating Center
*  info@sentinelsystem.org
*
*--------------------------------------------------------------------------------------------------
***************************************************************************************************;

%macro ms_findgap(InFile=, OutFile=, gap=);

  %put =====> MACRO CALLED: ms_findgap;
	
 /*----------------------------------------------------------------------------------------------------------
    Remove duplicate records by patid adate 
   ----------------------------------------------------------------------------------------------------------*/
    proc sort nodupkey data=&InFile. out=&OutFile.;
      by patid adate descending ExpireDt;
    run;
	
 /*----------------------------------------------------------------------------------------------------------
    Compute gaps when &gap is not equal to 0
	note: if &gap (washper) is 0 then all claims are deemed potential indedate with respect to own self
   ----------------------------------------------------------------------------------------------------------*/	
    data %if %eval(&gap. ne 0) %then %do;
         _&outFile. (drop = prev_expiredt gap daysuntreated)
	     %end;
	     &outfile  %if %eval(&gap. ne 0) %then %do; (drop = prev_expiredt gap daysuntreated) %end;;
      set &OutFile.;
      by patid adate descending ExpireDt;
	  %if %eval(&gap. ne 0) %then %do;
	    *Initialize gap and assign previous expiredt;
	     gap = 0;
	     prev_expiredt= lag(expiredt);
         if not missing(prev_expiredt) then do;
            DaysUntreated=Adate-prev_expiredt;
	     end;
	    *Reduce records to the first adate per patid;
         if first.adate then do;
	       if first.patid then do;
              gap = 1;
	    	  daysuntreated = 0;
	       end;
	       else do;
	         %if "&gap."="." %then %do;
               gap=0;  *If washper=., then only first date is valid;
             %end;
	    	 %else %do;
               gap=DaysUntreated > max(&gap.,0);
	    	 %end;
	      end;
	      output &outfile.;
	    end;
	    if gap then output _&outFile.;
	  %end;
	  %else %do;
	    if first.adate;
	  %end;
    run;
	
  /*----------------------------------------------------------------------------------------------------------
    Need to reapply gap against all claims (not just prior claim)
	note: if washper = 0, then all claims meet gap requirement
          if washper = ., then there are no prior claims as this has been already assessed
   ----------------------------------------------------------------------------------------------------------*/	
    %if %eval(&gap. > 0) %then %do;
        proc sql noprint undo_policy=none;
            create table &OutFile. as
			select ind.*
			from _&outfile. as ind
			left join(
               select distinct index.patid
			                  ,index.adate 
               from _&OutFile. as index, 
                    &OutFile. as Inc
               where index.Patid = Inc.Patid and index.adate ne inc.adate and %MS_PeriodsOverlap(period1=index.Adate-min(&gap.,99999) index.Adate-1,
                                                                                                 period2=Inc.ADate Inc.ExpireDt)) as ex
		    on ind.patid = ex.patid
			   and ind.adate = ex.adate
			where ind.patid ne ex.patid
			   and ind.adate ne ex.adate
			order by ind.patid
			        ,ind.adate;
        quit;
    %end;
	%else %if "&gap."="." %then %do;
	  proc datasets noprint library=work;
	    delete &OutFile.;
        change _&OutFile.=&OutFile.;
      run;    
    %end;

    proc datasets nowarn noprint lib=work;
        delete _&OutFile.;
    quit;

    %put NOTE: ********END OF MACRO: ms_findgap v1.5********;

%mend ms_findgap;