Reputation: 9359
I have a subscription that can be subscribed to every month, every two months or every 3 months. That's represented as a subscription_frequency
of 1, 2 or 3.
I then have a month_joined
property (1 through 12).
But I'm trying to work out, when someone should receive their subscription. So far I know I want to work out when the user will next receive a subscription.
So I'm adding 12 to the current month, then subtracting the month_joined
number, and then finding the remainder of their subscription_frequency
, to add on to the current month to tell them when their next box is due.
public function nextsub()
{
$remainder = ($current_month + 12 - $this->month_joined) % $this->subscription_frequency;
return $current_month + remainder;
}
But all my number are coming out screwy. Here is dump of users:
[
{
current_month: 3,
month_joined: 1,
subscription_frequency: 1,
next_box: 3
},
{
current_month: 3,
month_joined: 3,
subscription_frequency: 3,
next_box: 3
},
{
current_month: 3,
month_joined: 11,
subscription_frequency: 3,
next_box: 4<----------------- this is incorrect
},
{
current_month: 3,
month_joined: 12,
subscription_frequency: 3,
next_box: 3<----------------- this is incorrect
},
{
current_month: 3,
month_joined: 8,
subscription_frequency: 2,
next_box: 4
},
{
current_month: 3,
month_joined: 1,
subscription_frequency: 1,
next_box: 3
},
{
current_month: 3,
month_joined: 3,
subscription_frequency: 2,
next_box: 3
},
{
current_month: 3,
month_joined: 2,
subscription_frequency: 3,
next_box: 4 <----------------- this is incorrect
},
{
current_month: 3,
month_joined: 2,
subscription_frequency: 1,
next_box: 3
}
]
What's the matter with my maths?
Upvotes: 0
Views: 64
Reputation: 2970
This is hardly efficient but it should give you the next subscription month
public function nextsub()
{
$arrayofpossiblesubscriptionmonths=array();
for($i=1;$i<=12;$i++){
$submonth=$month_joined+($i*$this->subscription_frequency);
if($submonth>12){
$submonth=$submonth-12;
}
//this will create some duplicate months
$arrayofpossiblesubscriptionmonths[]=$submonth;
}
//cleanup duplicates
$uniquesubmonths=array_unique($arrayofpossiblesubscriptionmonths);
//fix the order
sort($uniquesubmonths);
//since they are in order. find the first one bigger than our current month
foreach($uniquesubmonths as $onesub){
if($onesub>$current_month){
return $onesub;
}
}
}
Here is a CodeViper in action with a slightly altered function so I could pass the variables in easier http://codepad.viper-7.com/9Er2pi
function nextsub($current_month,$month_joined,$subscription_frequency)
{
$arrayofpossiblesubscriptionmonths=array();
for($i=1;$i<=12;$i++){
$submonth=$month_joined+($i*$subscription_frequency);
if($submonth>12){
$submonth=$submonth-12;
}
//this will create some duplicate months
$arrayofpossiblesubscriptionmonths[]=$submonth;
}
//cleanup duplicates
$uniquesubmonths=array_unique($arrayofpossiblesubscriptionmonths);
//fix the order
sort($uniquesubmonths);
//since they are in order. find the first one bigger than our current month
foreach($uniquesubmonths as $onesub){
if($onesub>$current_month){
return $onesub;
}
}
}
$curmonth=3;
$monthjoined=1;
$sub_freq=1;
echo '<BR>Current month: '.$curmonth;
echo '<BR>Month Joined: '.$monthjoined;
echo '<BR>Subscription Frequency: '.$sub_freq;
echo '<BR>Next Subscription Month: '.nextsub($curmonth,$monthjoined,$sub_freq);
echo'<HR>';
$curmonth=3;
$monthjoined=11;
$sub_freq=3;
echo '<BR>Current month: '.$curmonth;
echo '<BR>Month Joined: '.$monthjoined;
echo '<BR>Subscription Frequency: '.$sub_freq;
echo '<BR>Next Subscription Month: '.nextsub($curmonth,$monthjoined,$sub_freq);
echo'<HR>';
$curmonth=3;
$monthjoined=8;
$sub_freq=2;
echo '<BR>Current month: '.$curmonth;
echo '<BR>Month Joined: '.$monthjoined;
echo '<BR>Subscription Frequency: '.$sub_freq;
echo '<BR>Next Subscription Month: '.nextsub($curmonth,$monthjoined,$sub_freq);
Output
Current month: 3
Month Joined: 1
Subscription Frequency: 1
Next Subscription Month: 4
Current month: 3
Month Joined: 11
Subscription Frequency: 3
Next Subscription Month: 5
Current month: 3
Month Joined: 8
Subscription Frequency: 2
Next Subscription Month: 4
Upvotes: 0
Reputation: 458
IMHO you could check if the current month is a month you should be sending the subscription (this doesn't check if you sent the subscription for the current month, this should be a separate functionality)
If you deliver in the month of subscription
enter code here
$shouldSubscriptionBeSent = ($currentMonth - $monthJoined) % $subscriptionFrequency === 0
If you deliver the next month after subscription
$shouldSubscriptionBeSent = ($currentMonth - $monthJoined - 1) % $subscriptionFrequency === 0
I think you should keep an array with the months you delivered, and the subscription month in fact should be a date, and afterwards you could find the subscription dates by adding the frequency months to the subscription date.
Upvotes: 1