Plugin Directory

Changeset 2482659


Ignore:
Timestamp:
02/27/2021 12:54:54 PM (5 years ago)
Author:
soraco
Message:
  • Fixed date parsing issue when manually processing a subscription payment.
  • Added new option to enable order processing when the order status is completed, to be used only in very special cases.
  • If you have created a Maintenance Plan attribute to allow customers to opt-in/out of purchasing a maintenance plan, a new option allows you to specify the label that you used for the maintenance plan attribute. QLM uses this identifier to associate this attribute to the QLM Maintenance Plan feature.
Location:
quick-license-manager/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • quick-license-manager/trunk/Readme.txt

    r2477729 r2482659  
    33Tags: quick license manager, software protection, ecommerce
    44Requires at least: 4.2
    5 Tested up to: 5.6
    6 Stable tag: 2.3.0
     5Tested up to: 5.6.2
     6Stable tag: 2.3.1
    77License: GPLv2
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    4040
    4141== Changelog ==
     42
     43= 2.3.1 - 02/27/2021 =
     44Fixed date parsing issue when manually processing a subscription payment.
     45Added new option to enable order processing when the order status is completed, to be used only in very special cases.
     46If you have created a Maintenance Plan attribute to allow customers to opt-in/out of purchasing a maintenance plan, a new option allows you to specify the label that you used for the maintenance plan attribute. QLM uses this identifier to associate this attribute to the QLM Maintenance Plan feature.
     47
    4248
    4349= 2.3.0 - 02/17/2021 =
  • quick-license-manager/trunk/classes/qlm_api_view.php

    r2477729 r2482659  
    362362            $qlm_categories = get_option( 'qlm_categories');
    363363            $qlm_user_role = get_option( 'qlm_user_role');
     364            $qlm_maintenance_plan_identifier = get_option( 'qlm_maintenance_plan_identifier');
    364365            $qlm_product_addon = get_option( 'qlm_product_addon');
    365366
     
    367368            $qlm_revoke_when_subscription_cancelled = get_option( 'qlm_revoke_when_subscription_cancelled');
    368369            $qlm_next_payment_date_based_on_schedule = get_option( 'qlm_next_payment_date_based_on_schedule');
    369            
     370            $qlm_process_order_on_status_completed = get_option( 'qlm_process_order_on_status_completed');
     371
    370372            $qlm_send_mail = get_option( 'qlm_send_mail');
    371373            $qlm_enable_log = get_option( 'qlm_enable_log');
     
    435437                            <div class="col-md-4" style="margin-top:0em;"></div>
    436438                            <div class="col-md-8" style="margin-top:0em;"><i>Specify the user role that should be assigned to the user after purchase.</i></div>
    437                            
     439                        </div>
     440                        <div class="row">
     441                            <div class="col-md-4" style="margin-top:1em;"><b>Maintenance Plan Identifier</b></div>
     442                            <div class="col-md-8" style="margin-top:1em;"><input class="form-control" type="text" value="<?php if($qlm_maintenance_plan_identifier){ echo $qlm_maintenance_plan_identifier; } ?>" name="qlm_maintenance_plan_identifier"></div>
     443                        </div>
     444                        <div class="row">
     445                            <div class="col-md-4" style="margin-top:0em;"></div>
     446                            <div class="col-md-8" style="margin-top:0em;"><i>If you have created a Maintenance Plan attribute to allow customers to opt-in/out of purchasing a maintenance plan, specify the label that you used for the maintenance plan attribute. QLM uses this identifier to associate this attribute to the QLM Maintenance Plan feature.</i></div>
    438447                        </div>
    439448                        <div class="row">
     
    471480                            <div class="col-md-4" style="margin-top:0em;"></div>
    472481                            <div class="col-md-8" style="margin-top:0em;"><i>By default, WooCommerce calculates the next payment date from the time of the last payment. This option calculates the next payment date from the scheduled payment date. This is required if you enabled WooCommerce Subscriptions Early Renewal.</i></div>
     482                        </div>
     483
     484                        <div class="row">
     485                            <div class="col-md-4" style="margin-top:1em;"><b>Process request when order status is completed (default is unchecked).</b></div>
     486                            <div class="col-md-8" style="margin-top:1em;"><input type="checkbox" value="1" <?php checked( '1', get_option( 'qlm_process_order_on_status_completed' ) ); ?> name="qlm_process_order_on_status_completed" id="qlm_process_order_on_status_completed"></div>
     487                        </div>
     488                        <div class="row">
     489                            <div class="col-md-4" style="margin-top:0em;"></div>
     490                            <div class="col-md-8" style="margin-top:0em;"><i>By default, QLM processes an order when the order status is "in progress" but not completed. This allows QLM to insert the generated license keys in the order. In some special cases, you may want to have QLM process the request only after the order status changes to completed. Beware that, if you enable this option, license keys will not be stored in the order.</i></div>
    473491                        </div>
    474492
  • quick-license-manager/trunk/wc_qlm.php

    r2477729 r2482659  
    22
    33/**
    4  * Plugin Name: WooCommerce - Quick License Manager Integration
     4 * Plugin Name: WooCommerce Quick License Manager Integration
    55 * Plugin URI: https://wordpress.org/plugins/quick-license-manager/
    66 * Description: Automates the creation of license keys when orders are placed with WooCommerce
    7  * Version: 2.3.0
     7 * Version: 2.3.1
    88 * Author: Soraco Technologies Inc.
    99 * Author URI: https://soraco.co
    1010 * WC requires at least: 4.0.0
    11  * WC tested up to: 4.4.1
     11 * WC tested up to: 5.0.0
    1212 */
    1313
     
    2121
    2222//
    23 //Debug Message Next Index: 565
     23//Debug Message Next Index: 610
    2424//
    2525
     
    289289            if ($qlm_send_mail == false)
    290290            {
    291                 debug_message(74, $order,  __FUNCTION__, 'mail_on_order_completed aborted because the option to send mail is disabled.');
     291                debug_message(74, $order,  __FUNCTION__, 'mail_on_order_completed skipped because the option to send mail is disabled.');
    292292                return;
    293293            }
     
    471471            debug_message(140, $order,  __FUNCTION__, 'Processing order_status_completed.');
    472472
    473             // if the product is downloadable, order_status_changed does not get triggered so we process the order here.
    474             if ($this->are_all_products_downloadable ($order))
    475             {
    476                 debug_message(141, $order,  __FUNCTION__, 'Detected all downloadable products. Processing this order now.');
     473            $qlm_process_order_on_status_completed = get_option('qlm_process_order_on_status_completed');
     474
     475            // check if we already processed this order, i.e. was order_status_changed already triggered
     476            $license_keys_metadata = qlm_get_order_meta ($order->id, '_qlm_license_keys', true);
     477            $license_keys_already_generated = true;
     478            if (is_null($license_keys_metadata) || $license_keys_metadata == '')
     479            {
     480                // if the order already has the license key, it means that we already processed it on the status changed event             
     481                $license_keys_already_generated = false;
     482            }
     483
     484            debug_message(141, $order,  __FUNCTION__, 'qlm_process_order_on_status_completed:'.$qlm_process_order_on_status_completed.' License Keys Data:'.$license_keys_metadata);
     485
     486            // If process order on status completed is true and no license keys have been created, try to process the order now
     487            if (($qlm_process_order_on_status_completed == true)  && ($license_keys_already_generated == false))
     488            {
     489                debug_message(142, $order,  __FUNCTION__, 'Processing this order now.');
    477490                $this->process_order ( $order );
     491            }
     492            else
     493            {
     494                debug_message(143, $order,  __FUNCTION__, 'Skipping processing order on orer_status_completed');               
    478495            }
    479496               
     
    486503        function are_all_products_downloadable ($order)
    487504        {
    488             return false;
     505            return false;           
    489506            debug_message(150, $order,  __FUNCTION__, 'Start');
    490507
     
    492509
    493510            foreach($items as $item)
    494             {
     511            {
    495512                $product_id = $item->get_product_id();
    496513                $product = wc_get_product ($product_id);
     
    498515                if ($product->is_downloadable() == false)
    499516                {
    500                     debug_message(155, $order,  __FUNCTION__, 'Found one product not downloadable');
     517                    debug_message(155, $order,  __FUNCTION__, 'Found one product not downloadable: '.$item['name']);
    501518                    return false;
    502519                }
     
    651668                {
    652669                    $set_order_completed = false;
    653                     debug_message(300, $order,  __FUNCTION__, 'Skipping non-qlm item:'.$item['name]']);
     670                    debug_message(300, $order,  __FUNCTION__, 'Skipping non-qlm item:'.$item['name']);
    654671                }
    655672            }
     
    848865        }
    849866
     867        function get_next_payment_date_from_wc ($order, $subscription)
     868        {
     869            if (is_null($subscription))
     870            {
     871                debug_message(566, $order,  __FUNCTION__, 'Subscription is null.');
     872                return null;
     873            }
     874            else
     875            {
     876                $next_payment_get_date_str = $subscription->get_date ('next_payment');
     877                if (($next_payment_get_date_str != '') && ($next_payment_get_date_str != '0'))
     878                {
     879                    $next_payment_get_date = new DateTime($next_payment_get_date_str);
     880                }
     881                debug_message(570, $order,  __FUNCTION__, 'get_date(next_payment):'.$next_payment_get_date_str);
     882
     883                $next_payment_calc_date_str = $subscription->calculate_date ('next_payment');
     884                if (($next_payment_calc_date_str != '') && ($next_payment_calc_date_str != '0'))
     885                {
     886                    $next_payment_calc_date = new DateTime($next_payment_calc_date_str);
     887                }
     888                debug_message(575, $order,  __FUNCTION__, 'calculate_date(next_payment):'.$next_payment_calc_date_str);
     889
     890                if (is_null($next_payment_get_date) && is_null($next_payment_calc_date))
     891                {
     892                    debug_message(580, $order,  __FUNCTION__, 'WC returned empty dates.');
     893                    return null;
     894                }
     895                else if (is_null($next_payment_get_date))
     896                {
     897                    debug_message(585, $order,  __FUNCTION__, 'Using date:'.$next_payment_calc_date_str);   
     898                    $next_payment_date_str = $next_payment_calc_date_str;
     899                }
     900                else if (is_null($next_payment_calc_date))
     901                {
     902                    debug_message(590, $order,  __FUNCTION__, 'Using date:'.$next_payment_get_date_str);   
     903                    $next_payment_date_str = $next_payment_get_date_str;
     904                }
     905                else
     906                {
     907                    if ( wcs_order_contains_renewal( $order->id ) )
     908                    {
     909                        debug_message(591, $order,  __FUNCTION__, 'This is a renewal of an existing subscription.');   
     910
     911                        // we have 2 dates, take the largest one
     912                        if ($next_payment_calc_date > $next_payment_get_date)
     913                        {
     914                            $next_payment_date_str = $next_payment_calc_date_str;
     915                        }
     916                        else
     917                        {
     918                            $next_payment_date_str = $next_payment_get_date_str;
     919                        }
     920                    }
     921                    else
     922                    {
     923                        debug_message(592, $order,  __FUNCTION__, 'This is the first order of a new subscription.');   
     924                        // this is a first order of a subscription
     925                        $next_payment_date_str = $next_payment_get_date_str;
     926                    }
     927                   
     928                    debug_message(595, $order,  __FUNCTION__, 'Using date:'.$next_payment_date_str);   
     929                                   
     930                }
     931
     932                $next_payment_date = new DateTime($next_payment_date_str);
     933                return $next_payment_date;
     934               
     935            }
     936            return null;
     937        }
     938
    850939        function process_simple_item ($qlm_v, $order, $item, $subscription)
    851940        {                       
     
    858947
    859948            if ($subscription != null)
    860             {
    861                 $use_next_payment_date = true;
    862                 $next_payment_date = new DateTime($subscription->get_date ('next_payment'));
    863                 $next_payment_date_str = $next_payment_date->format('Y-m-d');
    864 
    865                 debug_message(420, $order,  __FUNCTION__, 'Next Payment Date:'.$next_payment_date_str);
    866 
    867 
     949            {               
    868950                $qlm_object = new qlm_object();
    869                 $this->calculate_expiry_date ($order, $qlm_object, $item, $use_next_payment_date, $next_payment_date);
     951                $this->calculate_expiry_date ($order, $subscription, $qlm_object, $item);
    870952
    871953
     
    884966
    885967            return $res;
     968        }
     969
     970        function get_maintenance_plan_attribute_name()
     971        {
     972            $mpi= get_option( 'qlm_maintenance_plan_identifier');
     973            if (is_null ($mpi) == false)
     974            {
     975                $mpi = strtolower($mpi);
     976                $mpi = str_replace (" ", "-", $mpi);
     977                $mpi = "attribute_".$mpi;
     978            }
     979            else
     980            {
     981                $mpi = "attribute_maintenance-plan";
     982            }
     983
     984            return $mpi;
    886985        }
    887986
     
    9171016
    9181017            //Set maintenance plan option for api call accordingly
    919             if($attributes['attribute_maintenance-plan'] == 'Yes')
     1018            if($attributes[$this->get_maintenance_plan_attribute_name()] == 'Yes')
    9201019            {
     1020                debug_message(600, $order,  __FUNCTION__, 'Maintenance Plan is selected.');
    9211021                $yearly = 1;
    9221022            }
    9231023            else
    9241024            {
     1025                debug_message(605, $order,  __FUNCTION__, 'No Maintenance Plan selected.');
    9251026                $yearly = 0;
    9261027            }
    927            
    9281028
    9291029            if ($subscription != null)
    9301030            {
    931                 $use_next_payment_date = true;
    932                 $next_payment_date = new DateTime($subscription->get_date ('next_payment'));
    933                 $next_payment_date_str = $next_payment_date->format('Y-m-d');
    934 
    9351031                $qlm_object = new qlm_object();
    936                 $this->calculate_expiry_date ($order, $qlm_object, $item, $use_next_payment_date, $next_payment_date);
     1032                $this->calculate_expiry_date ($order, $subscription, $qlm_object, $item);
    9371033
    9381034                debug_message(405, $order,  __FUNCTION__, 'Detected recurring variable product. Product:'.$item['product_id'].' Frequency:'.$sp.' Interval:'.$sinterval.' Duration:'.$qlm_object->expiry_duration);
     
    9771073            }
    9781074
    979             $use_next_payment_date = true;
    980            
    981             $next_payment_date = new DateTime($subscription->calculate_date ('next_payment'));         
    982             $next_payment_date_str = $next_payment_date->format('Y-m-d');
    983 
    984             $next_payment_get_date = new DateTime($subscription->get_date ('next_payment'));
    985             $next_payment_get_date_str = $next_payment_get_date->format('Y-m-d');
    986 
    987             debug_message(535, $order,  __FUNCTION__, 'Calculated Next Payment Date:'.$next_payment_date_str);
    988             debug_message(536, $order,  __FUNCTION__, 'Get Next Payment Date:'.$next_payment_get_date_str);
     1075           
    9891076
    9901077            $set_order_completed = true;
     
    10021089                debug_message(491, $order,  __FUNCTION__, 'Starting to process subscription item:'.$item['name']);
    10031090
    1004                 $qlm_result = $this->process_recurring_subscription_item ($order, $subscription, $item, $use_next_payment_date, $next_payment_date);
     1091                $qlm_result = $this->process_recurring_subscription_item ($order, $subscription, $item);
    10051092
    10061093                if ($qlm_result == true)
     
    10331120        }
    10341121
    1035         function calculate_expiry_date ($order, $qlm_object, $item, $use_next_payment_date, $next_payment_date)
     1122        function calculate_expiry_date ($order, $subscription, $qlm_object, $item)
    10361123        {
    10371124
    10381125            debug_message(329, $order,  __FUNCTION__, 'calculate_expiry_date');
     1126
     1127            $next_payment_date = $this->get_next_payment_date_from_wc ($order, $subscription);
     1128            if (!is_null($next_payment_date))
     1129            {
     1130                $qlm_object->expiry_date = $next_payment_date->format('Y-m-d');
     1131                $use_next_payment_date = true;
     1132                return $qlm_object->expiry_date;
     1133            }
     1134           
     1135            debug_message(328, $order,  __FUNCTION__, 'WC returned a null expiry date. We will calculate it.');
    10391136
    10401137            // Calculate the duration
     
    11271224                $qlm_object->expiry_duration = -1; 
    11281225            }
    1129 
    1130          
    1131             if ($use_next_payment_date || ($sp == null))
    1132             {
    1133                 $qlm_object->expiry_date = $next_payment_date->format ('Y-m-d');
    1134             }
    1135             else
    1136             {
    1137                 $tmpdate = new DateTime($order->order_date);
    1138                 $tmpdate->modify ('+'.$qlm_object->expiry_duration.' day');
    1139 
    1140                 $qlm_object->expiry_date = $tmpdate->format ('Y-m-d');     
    1141             }
     1226           
     1227            $tmpdate = new DateTime($order->order_date);
     1228            $tmpdate->modify ('+'.$qlm_object->expiry_duration.' day');
     1229
     1230            $qlm_object->expiry_date = $tmpdate->format ('Y-m-d');     
     1231           
    11421232
    11431233
     
    11451235        }
    11461236
    1147         function process_recurring_subscription_item ($order, $subscription, $item, $use_next_payment_date, $next_payment_date)
     1237        function process_recurring_subscription_item ($order, $subscription, $item)
    11481238        {
    11491239            debug_message(540, $order,  __FUNCTION__, 'Start processing item: '.$item['name']);
     
    11591249                $qlm_object = new qlm_object();
    11601250
    1161                 $this->calculate_expiry_date ($order, $qlm_object, $item, $use_next_payment_date, $next_payment_date);
     1251                $this->calculate_expiry_date ($order, $subscription, $qlm_object, $item);
    11621252
    11631253                debug_message(435, $order,  __FUNCTION__, 'OrderDate: '.$order->order_date.' - Expiry Date: '.$qlm_object->expiry_date );
     
    11661256                $attributes = $prod->get_variation_attributes();                   
    11671257                   
    1168                 if($attributes['attribute_maintenance-plan'] == 'Yes')
     1258                if($attributes[$this->get_maintenance_plan_attribute_name] == 'Yes')
    11691259                {
    11701260                    $yearly = 1;                   
     
    11881278                $qlm_object = new qlm_object();
    11891279
    1190                 $this->calculate_expiry_date ($order, $qlm_object, $item, $use_next_payment_date, $next_payment_date);
     1280                $this->calculate_expiry_date ($order, $subscription, $qlm_object, $item);
    11911281                                   
    11921282                debug_message(465, $order,  __FUNCTION__, 'OrderDate: '.$order->order_date.' - Expiry Date: '.$qlm_object->expiry_date);
     
    13311421                $qlm_categories = $_POST['qlm_categories'];
    13321422                $qlm_user_role = $_POST['qlm_user_role'];
     1423                $qlm_maintenance_plan_identifier = $_POST['qlm_maintenance_plan_identifier'];
     1424               
    13331425                $qlm_product_addon= $_POST['qlm_product_addon'];
    13341426                $user_id = $_POST['qlm_user_id'];
     
    13371429                $qlm_revoke_when_subscription_cancelled= $_POST['qlm_revoke_when_subscription_cancelled'];
    13381430                $qlm_next_payment_date_based_on_schedule= $_POST['qlm_next_payment_date_based_on_schedule'];
     1431                $qlm_process_order_on_status_completed= $_POST['qlm_process_order_on_status_completed'];
     1432               
    13391433                $qlm_send_mail= $_POST['qlm_send_mail'];
    13401434                $qlm_enable_log = $_POST['qlm_enable_log'];
     
    13451439                update_option( 'qlm_categories', $qlm_categories );
    13461440                update_option( 'qlm_user_role', $qlm_user_role );
     1441                update_option( 'qlm_maintenance_plan_identifier', $qlm_maintenance_plan_identifier );               
    13471442                update_option( 'qlm_product_addon', $qlm_product_addon );
    13481443                update_option( 'qlm_userid', $user_id );
     
    13511446                update_option( 'qlm_revoke_when_subscription_cancelled', $qlm_revoke_when_subscription_cancelled );
    13521447                update_option( 'qlm_next_payment_date_based_on_schedule', $qlm_next_payment_date_based_on_schedule );
     1448                update_option( 'qlm_process_order_on_status_completed', $qlm_process_order_on_status_completed );
    13531449                update_option( 'qlm_send_mail', $qlm_send_mail );
    13541450                update_option( 'qlm_enable_log', $qlm_enable_log );
     
    14271523                   
    14281524                   
    1429                     if($attributes['attribute_maintenance-plan'] == 'Yes')
     1525                    if($attributes[$this->get_maintenance_plan_attribute_name()] == 'Yes')
    14301526                    {
    14311527                        $yearly = 1;
Note: See TracChangeset for help on using the changeset viewer.