Skip to content

Instantly share code, notes, and snippets.

@ipokkel
Created August 11, 2020 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ipokkel/b89417247fedc473515e9e980fc34996 to your computer and use it in GitHub Desktop.
Save ipokkel/b89417247fedc473515e9e980fc34996 to your computer and use it in GitHub Desktop.
Prorate initial payment per quarater based on subscription delay for a yearly (fiscal) recurring subscription
<?php
/**
* This recipe prorates initial payment per quarter based on subscription delay
* for a yearly (fiscal) recurring subscription.
*
* Requires Subscription Delay and Proration Add Ons.
*
* You can add this recipe to your site by creating a custom plugin
* or using the Code Snippets plugin available for free in the WordPress repository.
* Read this companion article for step-by-step directions on either method.
* https://www.paidmembershipspro.com/create-a-plugin-for-pmpro-customizations/
*/
function my_pmpro_checkout_level( $level ) {
// Only continue if Subscription Delays and Proration Add Ons are activated.
if ( ! function_exists( 'pmprosd_convert_date' ) || ! function_exists( 'pmprorate_trim_timestamp' ) ) {
return $level;
}
// Only continue for new members. (no "success" orders for this level)
global $current_user;
if ( ! empty( $current_user ) ) {
$order = new MemberOrder();
$order->getLastMemberOrder( $current_user->ID );
if ( ! empty( $order ) && ! empty( $order->membership_id ) && $order->membership_id == $level->id ) {
return $level;
}
}
// Bail if not annual subscription.
if ( empty( $level->cycle_period ) || 'year' !== strtolower( $level->cycle_period ) ) {
return $level;
}
// Get subscription start date for level.
$subscription_delay = get_option( 'pmpro_subscription_delay_' . $level->id );
if ( empty( $subscription_delay ) ) {
return $level;
}
if ( ! is_numeric( $subscription_delay ) ) {
$start_date = pmprosd_convert_date( $subscription_delay );
} else {
$start_date = date( 'Y-m-d', strtotime( '+ ' . intval( $subscription_delay ) . ' Days', current_time( 'timestamp' ) ) ) . 'T0:0:0';
}
// Prorate initial payment.
$next_payment_date = pmprorate_trim_timestamp( strtotime( $start_date, current_time( 'timestamp' ) ) );
$payment_date = pmprorate_trim_timestamp( strtotime( "-{$level->cycle_number} {$level->cycle_period}", $next_payment_date ) );
$today = pmprorate_trim_timestamp( current_time( 'timestamp' ) );
if ( $next_payment_date == $today ) {
return $level;
}
// Get difference in months.
$year1 = date( 'Y', $today );
$year2 = date( 'Y', $next_payment_date );
$month1 = date( 'm', $today );
$month2 = date( 'm', $next_payment_date );
$diff = ( ( $year2 - $year1 ) * 12 ) + ( $month2 - $month1 );
$quarters = ceil( $diff / 3 );
$price_prorated = round( ( ( $level->initial_payment / 4 ) * ( $quarters ) ), 2 );
// just in case we have a lower than minimum per quarter payment
if ( $price_prorated < round( ( $level->initial_payment / 4 ) * 1, 2 ) ) {
$price_prorated = round( ( $level->initial_payment / 4 ) * 1, 2 );
}
$level->initial_payment = $price_prorated;
// Make sure we don't run other proration code if we get to this point.
remove_filter( 'pmpro_checkout_level', 'pmprorate_pmpro_checkout_level', 10, 1 );
return $level;
}
add_filter( 'pmpro_checkout_level', 'my_pmpro_checkout_level', 5 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment