Changeset 2482659
- Timestamp:
- 02/27/2021 12:54:54 PM (5 years ago)
- Location:
- quick-license-manager/trunk
- Files:
-
- 3 edited
-
Readme.txt (modified) (2 diffs)
-
classes/qlm_api_view.php (modified) (4 diffs)
-
wc_qlm.php (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
quick-license-manager/trunk/Readme.txt
r2477729 r2482659 3 3 Tags: quick license manager, software protection, ecommerce 4 4 Requires at least: 4.2 5 Tested up to: 5.6 6 Stable tag: 2.3. 05 Tested up to: 5.6.2 6 Stable tag: 2.3.1 7 7 License: GPLv2 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 40 40 41 41 == Changelog == 42 43 = 2.3.1 - 02/27/2021 = 44 Fixed date parsing issue when manually processing a subscription payment. 45 Added new option to enable order processing when the order status is completed, to be used only in very special cases. 46 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. 47 42 48 43 49 = 2.3.0 - 02/17/2021 = -
quick-license-manager/trunk/classes/qlm_api_view.php
r2477729 r2482659 362 362 $qlm_categories = get_option( 'qlm_categories'); 363 363 $qlm_user_role = get_option( 'qlm_user_role'); 364 $qlm_maintenance_plan_identifier = get_option( 'qlm_maintenance_plan_identifier'); 364 365 $qlm_product_addon = get_option( 'qlm_product_addon'); 365 366 … … 367 368 $qlm_revoke_when_subscription_cancelled = get_option( 'qlm_revoke_when_subscription_cancelled'); 368 369 $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 370 372 $qlm_send_mail = get_option( 'qlm_send_mail'); 371 373 $qlm_enable_log = get_option( 'qlm_enable_log'); … … 435 437 <div class="col-md-4" style="margin-top:0em;"></div> 436 438 <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> 438 447 </div> 439 448 <div class="row"> … … 471 480 <div class="col-md-4" style="margin-top:0em;"></div> 472 481 <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> 473 491 </div> 474 492 -
quick-license-manager/trunk/wc_qlm.php
r2477729 r2482659 2 2 3 3 /** 4 * Plugin Name: WooCommerce -Quick License Manager Integration4 * Plugin Name: WooCommerce Quick License Manager Integration 5 5 * Plugin URI: https://wordpress.org/plugins/quick-license-manager/ 6 6 * Description: Automates the creation of license keys when orders are placed with WooCommerce 7 * Version: 2.3. 07 * Version: 2.3.1 8 8 * Author: Soraco Technologies Inc. 9 9 * Author URI: https://soraco.co 10 10 * WC requires at least: 4.0.0 11 * WC tested up to: 4.4.111 * WC tested up to: 5.0.0 12 12 */ 13 13 … … 21 21 22 22 // 23 //Debug Message Next Index: 56523 //Debug Message Next Index: 610 24 24 // 25 25 … … 289 289 if ($qlm_send_mail == false) 290 290 { 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.'); 292 292 return; 293 293 } … … 471 471 debug_message(140, $order, __FUNCTION__, 'Processing order_status_completed.'); 472 472 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.'); 477 490 $this->process_order ( $order ); 491 } 492 else 493 { 494 debug_message(143, $order, __FUNCTION__, 'Skipping processing order on orer_status_completed'); 478 495 } 479 496 … … 486 503 function are_all_products_downloadable ($order) 487 504 { 488 return false; 505 return false; 489 506 debug_message(150, $order, __FUNCTION__, 'Start'); 490 507 … … 492 509 493 510 foreach($items as $item) 494 {511 { 495 512 $product_id = $item->get_product_id(); 496 513 $product = wc_get_product ($product_id); … … 498 515 if ($product->is_downloadable() == false) 499 516 { 500 debug_message(155, $order, __FUNCTION__, 'Found one product not downloadable ');517 debug_message(155, $order, __FUNCTION__, 'Found one product not downloadable: '.$item['name']); 501 518 return false; 502 519 } … … 651 668 { 652 669 $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']); 654 671 } 655 672 } … … 848 865 } 849 866 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 850 939 function process_simple_item ($qlm_v, $order, $item, $subscription) 851 940 { … … 858 947 859 948 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 { 868 950 $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); 870 952 871 953 … … 884 966 885 967 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; 886 985 } 887 986 … … 917 1016 918 1017 //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') 920 1019 { 1020 debug_message(600, $order, __FUNCTION__, 'Maintenance Plan is selected.'); 921 1021 $yearly = 1; 922 1022 } 923 1023 else 924 1024 { 1025 debug_message(605, $order, __FUNCTION__, 'No Maintenance Plan selected.'); 925 1026 $yearly = 0; 926 1027 } 927 928 1028 929 1029 if ($subscription != null) 930 1030 { 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 935 1031 $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); 937 1033 938 1034 debug_message(405, $order, __FUNCTION__, 'Detected recurring variable product. Product:'.$item['product_id'].' Frequency:'.$sp.' Interval:'.$sinterval.' Duration:'.$qlm_object->expiry_duration); … … 977 1073 } 978 1074 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 989 1076 990 1077 $set_order_completed = true; … … 1002 1089 debug_message(491, $order, __FUNCTION__, 'Starting to process subscription item:'.$item['name']); 1003 1090 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); 1005 1092 1006 1093 if ($qlm_result == true) … … 1033 1120 } 1034 1121 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) 1036 1123 { 1037 1124 1038 1125 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.'); 1039 1136 1040 1137 // Calculate the duration … … 1127 1224 $qlm_object->expiry_duration = -1; 1128 1225 } 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 1142 1232 1143 1233 … … 1145 1235 } 1146 1236 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) 1148 1238 { 1149 1239 debug_message(540, $order, __FUNCTION__, 'Start processing item: '.$item['name']); … … 1159 1249 $qlm_object = new qlm_object(); 1160 1250 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); 1162 1252 1163 1253 debug_message(435, $order, __FUNCTION__, 'OrderDate: '.$order->order_date.' - Expiry Date: '.$qlm_object->expiry_date ); … … 1166 1256 $attributes = $prod->get_variation_attributes(); 1167 1257 1168 if($attributes[ 'attribute_maintenance-plan'] == 'Yes')1258 if($attributes[$this->get_maintenance_plan_attribute_name] == 'Yes') 1169 1259 { 1170 1260 $yearly = 1; … … 1188 1278 $qlm_object = new qlm_object(); 1189 1279 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); 1191 1281 1192 1282 debug_message(465, $order, __FUNCTION__, 'OrderDate: '.$order->order_date.' - Expiry Date: '.$qlm_object->expiry_date); … … 1331 1421 $qlm_categories = $_POST['qlm_categories']; 1332 1422 $qlm_user_role = $_POST['qlm_user_role']; 1423 $qlm_maintenance_plan_identifier = $_POST['qlm_maintenance_plan_identifier']; 1424 1333 1425 $qlm_product_addon= $_POST['qlm_product_addon']; 1334 1426 $user_id = $_POST['qlm_user_id']; … … 1337 1429 $qlm_revoke_when_subscription_cancelled= $_POST['qlm_revoke_when_subscription_cancelled']; 1338 1430 $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 1339 1433 $qlm_send_mail= $_POST['qlm_send_mail']; 1340 1434 $qlm_enable_log = $_POST['qlm_enable_log']; … … 1345 1439 update_option( 'qlm_categories', $qlm_categories ); 1346 1440 update_option( 'qlm_user_role', $qlm_user_role ); 1441 update_option( 'qlm_maintenance_plan_identifier', $qlm_maintenance_plan_identifier ); 1347 1442 update_option( 'qlm_product_addon', $qlm_product_addon ); 1348 1443 update_option( 'qlm_userid', $user_id ); … … 1351 1446 update_option( 'qlm_revoke_when_subscription_cancelled', $qlm_revoke_when_subscription_cancelled ); 1352 1447 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 ); 1353 1449 update_option( 'qlm_send_mail', $qlm_send_mail ); 1354 1450 update_option( 'qlm_enable_log', $qlm_enable_log ); … … 1427 1523 1428 1524 1429 if($attributes[ 'attribute_maintenance-plan'] == 'Yes')1525 if($attributes[$this->get_maintenance_plan_attribute_name()] == 'Yes') 1430 1526 { 1431 1527 $yearly = 1;
Note: See TracChangeset
for help on using the changeset viewer.