Last active
November 21, 2017 03:04
-
-
Save mattallan/9faf640bc2371b56ef61d0a1a5de6f66 to your computer and use it in GitHub Desktop.
Estimate billing periods between two timestamps (for WCS Resource) + unit tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Estimate the billing periods between two timestamps | |
* | |
* @since 1.0 | |
* @param int $from_timestamp | |
* @param int $to_timestamp | |
* @param string $billing_period | |
* @param string $billing_interval | |
* @return array | |
*/ | |
public function estimate_resource_billing_periods_between( $from_timestamp, $to_timestamp, $billing_period, $billing_interval ) { | |
$billing_periods_between = array(); | |
$counter = 0; | |
while ( $from_timestamp < $to_timestamp && $counter < 100 ) { | |
$current_billing_period = array( 'from_timestamp' => $from_timestamp ); | |
$next_timestamp = wcs_add_time( $billing_interval, $billing_period, $from_timestamp ); // use the same function used to calculate subscription billing periods to work out the exact billing | |
if ( $to_timestamp < $next_timestamp ) { | |
$current_billing_period['to_timestamp'] = $to_timestamp; | |
$current_billing_period['period_fraction'] = round( ( $from_timestamp - $to_timestamp ) / ( $from_timestamp - $next_timestamp ), 2); | |
} else { | |
$current_billing_period['to_timestamp'] = ( $to_timestamp - $next_timestamp > DAY_IN_SECONDS ) ? $next_timestamp : $to_timestamp; | |
$current_billing_period['period_fraction'] = 1; | |
} | |
$from_timestamp = $next_timestamp; | |
$billing_periods_between[] = $current_billing_period; | |
if ( $to_timestamp - $from_timestamp < DAY_IN_SECONDS ) { | |
break; | |
} | |
$counter++; | |
} | |
return $billing_periods_between; | |
} | |
public function provider_get_resource_billing_periods_between() { | |
return array( | |
// from and to timestamps exactly 1 month | |
0 => array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-01 14:21:40' ), | |
'billing_period' => 'month', | |
'billing_interval' => 1, | |
'expected_result' => array( | |
array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-01 14:21:40' ), | |
'period_fraction' => 1 | |
) | |
), | |
), | |
// from and to timstamps just over 1 month (20mins over) | |
1 => array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-01 14:40:40' ), | |
'billing_period' => 'month', | |
'billing_interval' => 1, | |
'expected_result' => array( | |
array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-01 14:40:40' ), | |
'period_fraction' => 1 | |
) | |
), | |
), | |
// ~1.5 billing periods found between the two dates | |
2 => array( | |
'from_timestamp' => strtotime( '2017-09-14 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-11-01 14:40:40' ), | |
'billing_period' => 'month', | |
'billing_interval' => 1, | |
'expected_result' => array( | |
array( | |
'from_timestamp' => strtotime( '2017-09-14 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-14 14:21:40' ), | |
'period_fraction' => 1 | |
), | |
array( | |
'from_timestamp' => strtotime( '2017-10-14 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-11-01 14:40:40' ), | |
'period_fraction' => 0.58 | |
), | |
), | |
), | |
// If for some reason the renewal is triggered 1 hour early - the billing period should still be 1 | |
3 => array( | |
'from_timestamp' => strtotime( '2017-09-14 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-14 12:40:40' ), | |
'billing_period' => 'month', | |
'billing_interval' => 1, | |
'expected_result' => array( | |
array( | |
'from_timestamp' => strtotime( '2017-09-14 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-10-14 12:40:40' ), | |
'period_fraction' => 1 | |
), | |
), | |
), | |
// If the billing period is only 15 days but the subscription renews monthly | |
4 => array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-09-16 12:40:40' ), | |
'billing_period' => 'month', | |
'billing_interval' => 1, | |
'expected_result' => array( | |
array( | |
'from_timestamp' => strtotime( '2017-09-01 14:21:40' ), | |
'to_timestamp' => strtotime( '2017-09-16 12:40:40' ), | |
'period_fraction' => 0.5 | |
), | |
), | |
), | |
); | |
} | |
/** | |
* Make sure get_days_in_period() is calculating the number of days properly | |
* | |
* | |
* @dataProvider provider_get_resource_billing_periods_between | |
* @group billing_periods_between | |
*/ | |
public function test_get_resource_billing_periods_between( $from_timestamp, $to_timestamp, $billing_period, $billing_interval, $expected_result ) { | |
$resource_mock = $this->getMockBuilder( 'WCSR_Resource' )->setMethods( array( 'get_date_created' ) )->disableOriginalConstructor()->getMock(); | |
$this->assertEquals( $expected_result, $resource_mock->get_resource_billing_periods_between( $from_timestamp, $to_timestamp, $billing_period, $billing_interval ) ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment