Search code examples
phpdatetimewhmcs

Calculate a due date in PHP


One of my co-workers recently installed an open-source script into our billing system. The purpose is to re-calculate the next due date for a service when the customer's service is paid for late. Example being service is due 11/20/2012, is suspended the next day, and then they pay for it 11/25/2012. This script is supposed to update the next due date to 12/25/2012, but is malfunctioning and changing (monthly) dates that should be 12/25/2012 to 1/25/2013 for some reason.

I think the issue is with the way the $month variable is being handled, but can't quite figure out where the issue is.

function calculate_postpone_due_date($billingcycle)
{
    switch($billingcycle)
    {
        case "Monthly":         $months = 1; break;
        case "Quarterly":       $months = 3; break;
        case "Semi-Annually":   $months = 6; break;
        case "Annually":        $months = 12; break;
        case "Biennially":      $months = 24; break;
        case "Triennially":     $months = 32; break;
        default:                $months = 0; break;
    }

    //we return FALSE for any other billing cycles: "One Time", "Free Account" etc, they are not recurring
    if ($months == 0)
    return FALSE;

    //a bit complex calculation based on day of the month
    //exactly like native whmcs logic do
    $year = date("Y");
    $month = date("m");
    $day = date("d");
    for ($i=1; $i<=$months; $i++)
    {
        $month++;
        if ($month == 13)
        {
            $month = 1;
            $year++;
        }
    }

    if (checkdate("$month", $day, $year))
    {
        return "$year-$month-$day";
    }
    else
    {
        //getting last day of the month
        $last_day = date("t", mktime(0, 0, 0, $month, 1, $year));
        return "$year-$month-$last_day";
    }
}

Solution

  • function calculate_postpone_due_date($billingcycle)
    {
        switch($billingcycle)
        {
            case "Monthly":         $months = 1; break;
            case "Quarterly":       $months = 3; break;
            case "Semi-Annually":   $months = 6; break;
            case "Annually":        $months = 12; break;
            case "Biennially":      $months = 24; break;
            case "Triennially":     $months = 36; break;
            default:                $months = 0; break;
        }
    
    
        if ($months == 0)
            return FALSE;    
    
        $today = date('Y-m-d');
        $next_due_date = strtotime($today.' + '.$months.' Months');
        return date('Y-m-d', $next_due_date);
    
    }