pub fn pay_at_level_by_anniversary_date_between_dates(&self, level: i32, start_date: NaiveDate, end_date: NaiveDate, mut anniversary_date: NaiveDate) -> Option<Vec<PayPeriod>> {
        let payscale = self.pay_scales.iter().find(|p| p.level == level);

        // use payscales to generate active_rates_of_pay for period

        // set businessdays calendar to weekends only
        let cal = bdays::calendars::WeekendsOnly;

        let payscale = match payscale {
            Some(p) => p,
            None => return None
        };

        // determine step based on anniversary date
        let step: i32 = 0;

        // Create vec of anniversary dates
        let mut steps: Vec<(NaiveDate, NaiveDate)> = Vec::new();

        // Ensure that anniversary date isn't after the start date
        if anniversary_date > start_date {
            anniversary_date = NaiveDate::from_ymd(
                start_date.year(),
                start_date.month(),
                start_date.day());
        }

        // add years as NaiveDate to Vec from anniversary date to max anniversary 
        // Note that we are adding more steps than required so we can keep a loop going
        // in return_active_pay_for_periods
        for y in anniversary_date.year()..end_date.year() + cmp::max(payscale.steps -1, 2) {
            let s = NaiveDate::from_ymd(y, anniversary_date.month(), anniversary_date.day());
            let e = NaiveDate::from_ymd(y, anniversary_date.month(), anniversary_date.day()) + Duration::days(365);
            steps.push((s, e));
        }

        println!("{:?}", steps);

        // Check for crossing Rates of pay based on dates and add each date to vec
        let mut relevant_rates_of_pay: Vec<&ActiveRateOfPay> = Vec::new();

        // Get vec of periods with annual pay, step, start and end dates
        // This needs to get all pay periods in range and split them for anniversary date
        // We should do this
        let active_rates = return_active_pay_for_period(&payscale, steps, start_date, end_date);

        // Create vec of PayPeriods
        let mut pay_periods: Vec<PayPeriod> = Vec::new();

        // loop through rates of pay and generate Vec<PayPeriod>
        let max_len = active_rates.len() as usize;

        for (i, rp) in active_rates.iter().enumerate() {

            // find the duration in hours within each rate_of_pay using max_len
            if i < max_len {

                // Start at our start date
                let period_start = rp.start_date;

                // Set calculation start date at period -1 to include day 1 of period
                let calculation_start = period_start - Duration::days(1);
                
                // identify the end date
                let mut period_end = rp.end_date;
                    
                let mut calculation_end: NaiveDate = period_end;
                
                if i == max_len - 1 {
                    // Set calculation start date at period +1 to include last day
                    calculation_end += Duration::days(1);
                } else {
                    period_end -= Duration::days(1);
                }

                // get work days in period
                let cal = bdays::HolidayCalendarCache::new(
                    bdays::calendars::WeekendsOnly,
                    // Using calculation start and end here while keeping the display dates
                    // the same as the user query
                    calculation_start,
                    // add two days to calendar dt_max to capture potential weekend
                    // and one day to calendar to capture our inclusive range
                    calculation_end + Duration::days(3),
                );

                // get business days, excluding only weekends
                // add 1 day to period_end to get inclusive range
                let days = cal.bdays(period_start, period_end + Duration::days(1));

                let hours = days as f64 * 7.5;

                let pay_for_period = (rp.salary as f64 / (261.0 * 7.5)) * hours as f64;

                let pay_for_period = round_to_2_decimal_points(pay_for_period);

                // create pay_period
                let p = PayPeriod {
                    start_date: period_start,
                    end_date: period_end,
                    work_days: round_to_2_decimal_points(hours / 7.5),
                    work_hours: round_to_2_decimal_points(hours),
                    step: rp.step,
                    annual_rate: rp.salary as f64,
                    hourly_rate: round_to_2_decimal_points(rp.salary as f64 / (261.0 * 7.5)), 
                    salary: pay_for_period,
                    level: level,
                    identifier: self.identifier,
                };
    
                // add pay_period to vec
                pay_periods.push(p);
            };


        };
        Some(pay_periods)
    }
/// Returns a vector of PayPeriods representing the expected pay including annual step increments for a range of work days inclusive of two YYYY-MM-DD dates.
/// For example, start_date: "2020-05-01" and end_date: "2020-05-05" would return pay for 1 day of 7.5 hours.
/// The function returns work days and holidays (for which public servants receive pay), but not weekends.
/// Also requires a level in integers and an anniversary date in YYYY-MM-DD.
/// If anniversary_date is after the start_date, it will be changed to be the same as the start date.
Returns a vector of PayPeriods representing the expected pay including annual step increments for a range of work days inclusive of two YYYY-MM-DD dates.
Returns a vector of PayPeriods representing the expected pay including annual step increments for a range of work days inclusive of two YYYY - MM - DD dates .
pub fn pay_at_level_by_anniversary_date_between_dates(&self, level: i32, start_date: NaiveDate, end_date: NaiveDate, mut anniversary_date: NaiveDate) -> Option<Vec<PayPeriod>> {
        let payscale = self.pay_scales.iter().find(|p| p.level == level);
        // use payscales to generate active_rates_of_pay for period
        // set businessdays calendar to weekends only
        let cal = bdays::calendars::WeekendsOnly;
        let payscale = match payscale {
            Some(p) => p,
            None => return None
        };
        // determine step based on anniversary date
        let step: i32 = 0;
        // Create vec of anniversary dates
        let mut steps: Vec<(NaiveDate, NaiveDate)> = Vec::new();
        // Ensure that anniversary date isn't after the start date
        if anniversary_date > start_date {
            anniversary_date = NaiveDate::from_ymd(
                start_date.year(),
                start_date.month(),
                start_date.day());
        }
        // add years as NaiveDate to Vec from anniversary date to max anniversary 
        // Note that we are adding more steps than required so we can keep a loop going
        // in return_active_pay_for_periods
        for y in anniversary_date.year()..end_date.year() + cmp::max(payscale.steps -1, 2) {
            let s = NaiveDate::from_ymd(y, anniversary_date.month(), anniversary_date.day());
            let e = NaiveDate::from_ymd(y, anniversary_date.month(), anniversary_date.day()) + Duration::days(365);
            steps.push((s, e));
        }
        println!("{:?}", steps);
        // Check for crossing Rates of pay based on dates and add each date to vec
        let mut relevant_rates_of_pay: Vec<&ActiveRateOfPay> = Vec::new();
        // Get vec of periods with annual pay, step, start and end dates
        // This needs to get all pay periods in range and split them for anniversary date
        // We should do this
        let active_rates = return_active_pay_for_period(&payscale, steps, start_date, end_date);
        // Create vec of PayPeriods
        let mut pay_periods: Vec<PayPeriod> = Vec::new();
        // loop through rates of pay and generate Vec<PayPeriod>
        let max_len = active_rates.len() as usize;
        for (i, rp) in active_rates.iter().enumerate() {
            // find the duration in hours within each rate_of_pay using max_len
            if i < max_len {
                // Start at our start date
                let period_start = rp.start_date;
                // Set calculation start date at period -1 to include day 1 of period
                let calculation_start = period_start - Duration::days(1);
                // identify the end date
                let mut period_end = rp.end_date;
                let mut calculation_end: NaiveDate = period_end;
                if i == max_len - 1 {
                    // Set calculation start date at period +1 to include last day
                    calculation_end += Duration::days(1);
                } else {
                    period_end -= Duration::days(1);
                }
                // get work days in period
                let cal = bdays::HolidayCalendarCache::new(
                    bdays::calendars::WeekendsOnly,
                    // Using calculation start and end here while keeping the display dates
                    // the same as the user query
                    calculation_start,
                    // add two days to calendar dt_max to capture potential weekend
                    // and one day to calendar to capture our inclusive range
                    calculation_end + Duration::days(3),
                );
                // get business days, excluding only weekends
                // add 1 day to period_end to get inclusive range
                let days = cal.bdays(period_start, period_end + Duration::days(1));
                let hours = days as f64 * 7.5;
                let pay_for_period = (rp.salary as f64 / (261.0 * 7.5)) * hours as f64;
                let pay_for_period = round_to_2_decimal_points(pay_for_period);
                // create pay_period
                let p = PayPeriod {
                    start_date: period_start,
                    end_date: period_end,
                    work_days: round_to_2_decimal_points(hours / 7.5),
                    work_hours: round_to_2_decimal_points(hours),
                    step: rp.step,
                    annual_rate: rp.salary as f64,
                    hourly_rate: round_to_2_decimal_points(rp.salary as f64 / (261.0 * 7.5)), 
                    salary: pay_for_period,
                    level: level,
                    identifier: self.identifier,
                };
                // add pay_period to vec
                pay_periods.push(p);
            };
        };
        Some(pay_periods)
    }
pub fn pay_at_level_by_anniversary_date_between_dates ( & self , level : i32 , start_date : NaiveDate , end_date : NaiveDate , mut anniversary_date : NaiveDate ) -> Option < Vec < PayPeriod > > { let payscale = self . pay_scales . iter ( ) . find ( | p | p . level == level ) ; // use payscales to generate active_rates_of_pay for period // set businessdays calendar to weekends only let cal = bdays :: calendars :: WeekendsOnly ; let payscale = match payscale { Some ( p ) => p , None => return None } ; // determine step based on anniversary date let step : i32 = 0 ; // Create vec of anniversary dates let mut steps : Vec < ( NaiveDate , NaiveDate ) > = Vec :: new ( ) ; // Ensure that anniversary date isn't after the start date if anniversary_date > start_date { anniversary_date = NaiveDate :: from_ymd ( start_date . year ( ) , start_date . month ( ) , start_date . day ( ) ) ; } // add years as NaiveDate to Vec from anniversary date to max anniversary  // Note that we are adding more steps than required so we can keep a loop going // in return_active_pay_for_periods for y in anniversary_date . year ( ) .. end_date . year ( ) + cmp :: max ( payscale . steps - 1 , 2 ) { let s = NaiveDate :: from_ymd ( y , anniversary_date . month ( ) , anniversary_date . day ( ) ) ; let e = NaiveDate :: from_ymd ( y , anniversary_date . month ( ) , anniversary_date . day ( ) ) + Duration :: days ( 365 ) ; steps . push ( ( s , e ) ) ; } println ! ( " " steps ) ; // Check for crossing Rates of pay based on dates and add each date to vec let mut relevant_rates_of_pay : Vec < & ActiveRateOfPay > = Vec :: new ( ) ; // Get vec of periods with annual pay, step, start and end dates // This needs to get all pay periods in range and split them for anniversary date // We should do this let active_rates = return_active_pay_for_period ( & payscale , steps , start_date , end_date ) ; // Create vec of PayPeriods let mut pay_periods : Vec < PayPeriod > = Vec :: new ( ) ; // loop through rates of pay and generate Vec<PayPeriod> let max_len = active_rates . len ( ) as usize ; for ( i , rp ) in active_rates . iter ( ) . enumerate ( ) { // find the duration in hours within each rate_of_pay using max_len if i < max_len { // Start at our start date let period_start = rp . start_date ; // Set calculation start date at period -1 to include day 1 of period let calculation_start = period_start - Duration :: days ( 1 ) ; // identify the end date let mut period_end = rp . end_date ; let mut calculation_end : NaiveDate = period_end ; if i == max_len - 1 { // Set calculation start date at period +1 to include last day calculation_end += Duration :: days ( 1 ) ; } else { period_end -= Duration :: days ( 1 ) ; } // get work days in period let cal = bdays :: HolidayCalendarCache :: new ( bdays :: calendars :: WeekendsOnly , // Using calculation start and end here while keeping the display dates // the same as the user query calculation_start , // add two days to calendar dt_max to capture potential weekend // and one day to calendar to capture our inclusive range calculation_end + Duration :: days ( 3 ) , ) ; // get business days, excluding only weekends // add 1 day to period_end to get inclusive range let days = cal . bdays ( period_start , period_end + Duration :: days ( 1 ) ) ; let hours = days as f64 * 7.5 ; let pay_for_period = ( rp . salary as f64 / ( 261.0 * 7.5 ) ) * hours as f64 ; let pay_for_period = round_to_2_decimal_points ( pay_for_period ) ; // create pay_period let p = PayPeriod { start_date : period_start , end_date : period_end , work_days : round_to_2_decimal_points ( hours / 7.5 ) , work_hours : round_to_2_decimal_points ( hours ) , step : rp . step , annual_rate : rp . salary as f64 , hourly_rate : round_to_2_decimal_points ( rp . salary as f64 / ( 261.0 * 7.5 ) ) , salary : pay_for_period , level : level , identifier : self . identifier , } ; // add pay_period to vec pay_periods . push ( p ) ; } ; } ; Some ( pay_periods ) }
Returns a vector of PayPeriods representing the expected pay including annual step increments for a range of work days inclusive of two YYYY-MM-DD dates.
Returns a vector of PayPeriods representing the expected pay including annual step increments for a range of work days inclusive of two YYYY - MM - DD dates .
&self
level
i32
start_date
NaiveDate
end_date
NaiveDate
anniversary_date
NaiveDate