From 153a2cd7eda49ebde5b6a3e939c3e48779376171 Mon Sep 17 00:00:00 2001 From: Prospress Inc Date: Wed, 23 Nov 2016 15:34:50 +0100 Subject: [PATCH] 2.1.0 --- assets/css/about.css | 37 +- assets/css/admin.css | 202 +- assets/css/dashboard.css | 16 + .../images/add-edit-subscription-screen.png | Bin 40200 -> 0 bytes assets/images/admin-change-payment-method.jpg | Bin 59011 -> 0 bytes assets/images/billing-schedules-meta-box.png | Bin 38624 -> 0 bytes assets/images/checkout-recurring-totals.png | Bin 68524 -> 0 bytes assets/images/drip-downloadable-content.jpg | Bin 71107 -> 0 bytes assets/images/view-subscription.png | Bin 255564 -> 0 bytes assets/js/admin/jquery.flot.axislabels.js | 466 +++ assets/js/admin/jquery.flot.axislabels.min.js | 1 + assets/js/admin/jquery.flot.orderBars.js | 201 ++ assets/js/admin/jquery.flot.orderBars.min.js | 23 + assets/js/admin/reports.js | 65 + assets/js/admin/wcs-meta-boxes-order.js | 8 + changelog.txt | 70 +- .../abstracts/abstract-wcs-retry-store.php | 107 + includes/abstracts/abstract-wcs-scheduler.php | 6 +- .../admin/class-wc-subscriptions-admin.php | 289 +- includes/admin/class-wcs-admin-meta-boxes.php | 64 + includes/admin/class-wcs-admin-post-types.php | 150 +- includes/admin/class-wcs-admin-reports.php | 171 + .../class-wcs-meta-box-payment-retries.php | 33 + .../class-wcs-meta-box-subscription-data.php | 4 +- ...ass-wcs-meta-box-subscription-schedule.php | 2 +- .../views/html-related-orders-row.php | 20 +- .../meta-boxes/views/html-retries-table.php | 75 + .../views/html-subscription-schedule.php | 2 +- .../class-wcs-report-cache-manager.php | 264 ++ .../reports/class-wcs-report-dashboard.php | 100 + .../class-wcs-report-retention-rate.php | 243 ++ ...ss-wcs-report-subscription-by-customer.php | 278 ++ ...ass-wcs-report-subscription-by-product.php | 260 ++ ...wcs-report-subscription-events-by-date.php | 921 ++++++ ...-wcs-report-subscription-payment-retry.php | 389 +++ ...-wcs-report-upcoming-recurring-revenue.php | 421 +++ .../admin/views/html-report-by-period.php | 20 + ...-wc-rest-subscription-notes-controller.php | 36 + ...class-wc-rest-subscriptions-controller.php | 412 +++ .../class-wc-api-subscriptions-customers.php | 0 .../class-wc-api-subscriptions.php | 0 ...lass-wc-product-subscription-variation.php | 14 +- includes/class-wc-product-subscription.php | 28 +- ...class-wc-product-variable-subscription.php | 30 +- includes/class-wc-subscription.php | 182 +- includes/class-wc-subscriptions-cart.php | 207 +- includes/class-wc-subscriptions-coupon.php | 24 - includes/class-wc-subscriptions-email.php | 73 +- includes/class-wc-subscriptions-manager.php | 138 +- includes/class-wc-subscriptions-order.php | 270 +- includes/class-wc-subscriptions-product.php | 201 +- .../class-wc-subscriptions-renewal-order.php | 102 - includes/class-wc-subscriptions-switcher.php | 540 ++- .../class-wc-subscriptions-synchroniser.php | 76 +- includes/class-wcs-action-scheduler.php | 53 +- includes/class-wcs-api.php | 35 +- includes/class-wcs-cart-initial-payment.php | 16 +- includes/class-wcs-cart-renewal.php | 181 +- includes/class-wcs-cart-resubscribe.php | 164 +- includes/class-wcs-cart-switch.php | 119 + .../class-wcs-change-payment-method-admin.php | 2 +- includes/class-wcs-limiter.php | 241 ++ includes/class-wcs-query.php | 3 + includes/class-wcs-retry-manager.php | 321 ++ includes/class-wcs-webhooks.php | 39 +- ...class-wcs-email-cancelled-subscription.php | 18 +- ...email-customer-completed-renewal-order.php | 10 +- ...-email-customer-completed-switch-order.php | 10 +- ...class-wcs-email-customer-payment-retry.php | 134 + ...mail-customer-processing-renewal-order.php | 10 +- ...ass-wcs-email-customer-renewal-invoice.php | 29 +- .../class-wcs-email-expired-subscription.php | 165 + .../class-wcs-email-new-renewal-order.php | 10 +- .../class-wcs-email-new-switch-order.php | 10 +- .../class-wcs-email-on-hold-subscription.php | 165 + .../emails/class-wcs-email-payment-retry.php | 107 + ...lass-wc-subscriptions-payment-gateways.php | 40 +- includes/gateways/paypal/class-wcs-paypal.php | 33 +- .../includes/admin/class-wcs-paypal-admin.php | 34 +- ...rence-transaction-api-response-payment.php | 3 +- ...pal-reference-transaction-api-response.php | 31 + ...s-wcs-paypal-reference-transaction-api.php | 5 + ...-paypal-standard-change-payment-method.php | 4 +- ...cs-paypal-standard-ipn-failure-handler.php | 140 + .../class-wcs-paypal-standard-switcher.php | 40 +- .../class-wcs-paypal-status-manager.php | 19 + .../action-scheduler/action-scheduler.php | 24 +- .../classes/ActionScheduler_CronSchedule.php | 4 +- .../ActionScheduler_wpCommentLogger.php | 41 +- .../payment-retry/class-wcs-retry-admin.php | 144 + .../payment-retry/class-wcs-retry-email.php | 118 + .../class-wcs-retry-post-store.php | 160 + .../payment-retry/class-wcs-retry-rule.php | 95 + .../payment-retry/class-wcs-retry-rules.php | 112 + includes/payment-retry/class-wcs-retry.php | 155 + .../class-wc-subscriptions-upgrader.php | 40 +- includes/upgrades/class-wcs-repair-2-0-2.php | 4 +- includes/upgrades/class-wcs-repair-2-0.php | 20 +- includes/upgrades/class-wcs-upgrade-2-0.php | 2 +- includes/upgrades/class-wcs-upgrade-2-1.php | 54 + .../upgrades/class-wcs-upgrade-logger.php | 2 +- includes/upgrades/templates/wcs-about-2-0.php | 196 ++ includes/upgrades/templates/wcs-about.php | 189 +- includes/wcs-cart-functions.php | 8 +- includes/wcs-compatibility-functions.php | 45 + includes/wcs-formatting-functions.php | 25 + includes/wcs-helper-functions.php | 2 +- includes/wcs-limit-functions.php | 47 + includes/wcs-order-functions.php | 118 +- includes/wcs-renewal-functions.php | 14 +- includes/wcs-resubscribe-functions.php | 4 +- includes/wcs-time-functions.php | 144 +- includes/wcs-user-functions.php | 17 +- languages/woocommerce-subscriptions.pot | 2941 ++++++++++++----- readme.txt | 6 +- .../order-shipping-html.php | 0 .../order-tax-html.php | 0 templates/admin/html-variation-price.php | 22 +- .../admin/html-variation-synchronisation.php | 8 +- templates/emails/admin-new-renewal-order.php | 82 +- templates/emails/admin-new-switch-order.php | 84 +- templates/emails/admin-payment-retry.php | 52 + templates/emails/cancelled-subscription.php | 77 +- .../customer-completed-renewal-order.php | 48 +- .../customer-completed-switch-order.php | 82 +- templates/emails/customer-payment-retry.php | 31 + .../customer-processing-renewal-order.php | 71 +- templates/emails/customer-renewal-invoice.php | 44 +- templates/emails/email-order-details.php | 59 + templates/emails/expired-subscription.php | 62 + templates/emails/on-hold-subscription.php | 62 + .../emails/plain/admin-new-renewal-order.php | 54 +- .../emails/plain/admin-new-switch-order.php | 69 +- .../emails/plain/admin-payment-retry.php | 46 + .../emails/plain/cancelled-subscription.php | 57 +- .../customer-completed-renewal-order.php | 50 +- .../plain/customer-completed-switch-order.php | 62 +- .../emails/plain/customer-payment-retry.php | 27 + .../customer-processing-renewal-order.php | 50 +- .../emails/plain/customer-renewal-invoice.php | 56 +- .../emails/plain/email-order-details.php | 31 + .../emails/plain/expired-subscription.php | 52 + .../emails/plain/on-hold-subscription.php | 48 + templates/emails/plain/subscription-info.php | 16 +- templates/emails/subscription-info.php | 18 +- templates/myaccount/related-orders.php | 2 +- templates/myaccount/view-subscription.php | 151 +- .../add-to-cart/subscription.php | 14 +- .../add-to-cart/variable-subscription.php | 10 +- wcs-functions.php | 36 +- woocommerce-subscriptions.php | 155 +- 151 files changed, 12316 insertions(+), 3635 deletions(-) create mode 100644 assets/css/dashboard.css delete mode 100644 assets/images/add-edit-subscription-screen.png delete mode 100644 assets/images/admin-change-payment-method.jpg delete mode 100644 assets/images/billing-schedules-meta-box.png delete mode 100644 assets/images/checkout-recurring-totals.png delete mode 100644 assets/images/drip-downloadable-content.jpg delete mode 100644 assets/images/view-subscription.png create mode 100644 assets/js/admin/jquery.flot.axislabels.js create mode 100644 assets/js/admin/jquery.flot.axislabels.min.js create mode 100644 assets/js/admin/jquery.flot.orderBars.js create mode 100644 assets/js/admin/jquery.flot.orderBars.min.js create mode 100644 assets/js/admin/reports.js create mode 100644 assets/js/admin/wcs-meta-boxes-order.js create mode 100644 includes/abstracts/abstract-wcs-retry-store.php create mode 100644 includes/admin/class-wcs-admin-reports.php create mode 100644 includes/admin/meta-boxes/class-wcs-meta-box-payment-retries.php create mode 100644 includes/admin/meta-boxes/views/html-retries-table.php create mode 100644 includes/admin/reports/class-wcs-report-cache-manager.php create mode 100644 includes/admin/reports/class-wcs-report-dashboard.php create mode 100644 includes/admin/reports/class-wcs-report-retention-rate.php create mode 100644 includes/admin/reports/class-wcs-report-subscription-by-customer.php create mode 100644 includes/admin/reports/class-wcs-report-subscription-by-product.php create mode 100644 includes/admin/reports/class-wcs-report-subscription-events-by-date.php create mode 100644 includes/admin/reports/class-wcs-report-subscription-payment-retry.php create mode 100644 includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php create mode 100644 includes/admin/views/html-report-by-period.php create mode 100644 includes/api/class-wc-rest-subscription-notes-controller.php create mode 100644 includes/api/class-wc-rest-subscriptions-controller.php rename includes/api/{ => legacy}/class-wc-api-subscriptions-customers.php (100%) rename includes/api/{ => legacy}/class-wc-api-subscriptions.php (100%) create mode 100644 includes/class-wcs-cart-switch.php create mode 100644 includes/class-wcs-limiter.php create mode 100644 includes/class-wcs-retry-manager.php create mode 100644 includes/emails/class-wcs-email-customer-payment-retry.php create mode 100644 includes/emails/class-wcs-email-expired-subscription.php create mode 100644 includes/emails/class-wcs-email-on-hold-subscription.php create mode 100644 includes/emails/class-wcs-email-payment-retry.php create mode 100644 includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-failure-handler.php create mode 100644 includes/payment-retry/class-wcs-retry-admin.php create mode 100644 includes/payment-retry/class-wcs-retry-email.php create mode 100644 includes/payment-retry/class-wcs-retry-post-store.php create mode 100644 includes/payment-retry/class-wcs-retry-rule.php create mode 100644 includes/payment-retry/class-wcs-retry-rules.php create mode 100644 includes/payment-retry/class-wcs-retry.php create mode 100644 includes/upgrades/class-wcs-upgrade-2-1.php create mode 100644 includes/upgrades/templates/wcs-about-2-0.php create mode 100644 includes/wcs-compatibility-functions.php create mode 100644 includes/wcs-limit-functions.php rename templates/admin/{post-types/writepanels => deprecated}/order-shipping-html.php (100%) rename templates/admin/{post-types/writepanels => deprecated}/order-tax-html.php (100%) create mode 100644 templates/emails/admin-payment-retry.php create mode 100644 templates/emails/customer-payment-retry.php create mode 100644 templates/emails/email-order-details.php create mode 100644 templates/emails/expired-subscription.php create mode 100644 templates/emails/on-hold-subscription.php create mode 100644 templates/emails/plain/admin-payment-retry.php create mode 100644 templates/emails/plain/customer-payment-retry.php create mode 100644 templates/emails/plain/email-order-details.php create mode 100644 templates/emails/plain/expired-subscription.php create mode 100644 templates/emails/plain/on-hold-subscription.php diff --git a/assets/css/about.css b/assets/css/about.css index 8d2eab9..61667f2 100644 --- a/assets/css/about.css +++ b/assets/css/about.css @@ -1,6 +1,12 @@ /*------------------------------------------------------------------------------ - Subscriptions 2.0 About Page CSS + Subscriptions About Page CSS ------------------------------------------------------------------------------*/ +ul { + list-style-type: disc; + padding-left: 1.6em; + margin-top: 0; + margin-bottom: 1.6em; +} .wcs-badge:before { font-family: WooCommerce !important; content: "\e03d"; @@ -34,8 +40,26 @@ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,.2); box-shadow: 0 1px 3px rgba(0,0,0,.2); } +.about-wrap h2 { + border-bottom: 1px solid #DDD; + margin: 0; + padding: 1em 0; +} +.about-wrap .changelog { + margin-bottom: 0; +} .about-wrap .feature-section { - padding-bottom: 2em; + padding-top: 1.6em; + padding-bottom: 0.4em; + border-bottom: 1px solid #DDD; +} +.about-wrap .still-more .feature-section { + padding-top: 0; + padding-bottom: 0.4em; + border-bottom: 1px solid #DDD; +} +.about-wrap .under-the-hood { + padding-top: 0; } .about-wrap .wcs-badge { position: absolute; @@ -75,10 +99,11 @@ .woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary, .woocommerce-message a.button-primary:focus, p.woocommerce-actions a.button-primary:focus, .woocommerce-message a.button-primary:active, p.woocommerce-actions a.button-primary:active { - background: #cc99c2; + background: #b366a4; border-color: #b366a4; -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15); box-shadow: inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15); + text-shadow: 0 -1px 1px #b366a4, 1px 0 1px #b366a4, 0 1px 1px #b366a4, -1px 0 1px #b366a4; color: #fff; text-decoration: none; } @@ -95,7 +120,8 @@ border-color: #aa559a; } -.woocommerce-message a.docs,.woocommerce-message a.skip,p.woocommerce-actions a.docs,p.woocommerce-actions a.skip { +.woocommerce-message a.skip, +p.woocommerce-actions a.skip { opacity: .7; } @@ -120,6 +146,9 @@ p.woocommerce-actions { .about-wrap .feature-section.two-col .col { float: left; } +.about-wrap .feature-section .col { + margin-top: 1em; +} .about-wrap .feature-section .col.last-feature { margin-right: 0; } diff --git a/assets/css/admin.css b/assets/css/admin.css index 68d27bb..184be13 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -90,54 +90,47 @@ a.close-subscriptions-search { } /* Edit Product/Subscriptions Page */ -.woocommerce_options_panel .subscription_pricing { - float: left; - clear: both; - height: 100%; - width: 100%; +.woocommerce_options_panel ._subscription_price_fields .wrap, +.woocommerce_options_panel ._subscription_trial_length_field .wrap, +.woocommerce_options_panel ._subscription_payment_sync_date_day_field .wrap { + display: block; + width: 50%; } -.woocommerce_options_panel .subscription_pricing .description { - font-style: normal; +@media only screen and (max-width:1280px){ + .woocommerce_options_panel ._subscription_price_fields .wrap, + .woocommerce_options_panel ._subscription_trial_length_field .wrap, + .woocommerce_options_panel ._subscription_payment_sync_date_day_field .wrap { + width:80%; + } } -.subscription_pricing .form-field, -.subscription_pricing .form-field *, -.variable_subscription_pricing .form-field, -.variable_subscription_pricing .form-field *, -.variable_subscription_trial .form-field, -.variable_subscription_trial .form-field * { - float:left; +.woocommerce_options_panel ._subscription_price_fields .wrap input, +.woocommerce_options_panel ._subscription_price_fields .wrap select { + width:30.75%; + margin-right:3.8%; } -p._subscription_price_field, -p._subscription_period_field, -p._subscription_length_field { - display: inline-block; +.woocommerce_options_panel ._subscription_trial_length_field .wrap input, +.woocommerce_options_panel ._subscription_trial_length_field .wrap select, +.woocommerce_options_panel ._subscription_payment_sync_date_day_field .wrap input, +.woocommerce_options_panel ._subscription_payment_sync_date_day_field .wrap select { + width:48%; + margin-right:3.8%; } -.woocommerce_options_panel input[type=text].wc_input_subscription_price, -.woocommerce_options_panel input[type=text].wc_input_subscription_intial_price, -.woocommerce_options_panel input[type=text].wc_input_subscription_trial_length, -.woocommerce_options_panel input[type=text].wc_input_subscription_payment_sync { - width: 5.5em; +.woocommerce_options_panel ._subscription_price_fields .wrap .last, +.woocommerce_options_panel ._subscription_trial_length_field .wrap .last, +.woocommerce_options_panel ._subscription_payment_sync_date_day_field .wrap .last { + margin-right:0 !important; } -p._subscription_period_field label, -p._subscription_length_field label, -p._subscription_period_interval_field label, -p._subscription_trial_period_field label, + .wc-metaboxes-wrapper .wc-metabox table td p._subscription_price_field label, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_period_field label, -.wc-metaboxes-wrapper .wc-metabox table td p._subscription_length_field label, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_period_interval_field label, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_trial_length_field label, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_trial_period_field label, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_payment_sync_field label { display: none; } -#woocommerce-product-data .woocommerce_options_panel p._subscription_price_field { - padding-right: 0 !important; -} -p._subscription_price_field input, + .wc-metaboxes-wrapper .wc-metabox table td p._subscription_price_field input, -p._subscription_sign_up_fee_field input, -p._subscription_trial_length_field input, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_trial_length_field input, .wc-metaboxes-wrapper .wc-metabox table td p._subscription_payment_sync_field input { width: 5em; @@ -145,32 +138,20 @@ p._subscription_trial_length_field input, .woocommerce_options_panel #sale-price-period { margin-right: 1em; } -.wc_input_subscription_length { - min-width: 90px; -} -.wc-metaboxes-wrapper .wc-metabox table td .wc_input_subscription_length { - width: 90px; -} -._subscription_trial_period { - min-width: 7.1em; -} + .wc-metaboxes-wrapper .wc-metabox table td ._subscription_trial_period { width: 7.1em; } -#woocommerce-product-data .woocommerce_options_panel p._subscription_period_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_length_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_period_interval_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_trial_period_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_payment_sync_date_month_field { - padding: 5px 0 5px 5px !important; -} + #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_price_field { width: 70px !important; } +#woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_length_field, #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_sign_up_fee_field { width: 100% !important; } #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_price_field, +#woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_length_field, #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_sign_up_fee_field, #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_trial_length_field, #woocommerce-product-data .wc-metaboxes-wrapper .wc-metabox table td p._subscription_payment_sync_field { @@ -204,24 +185,6 @@ p._subscription_trial_length_field input, margin-left: 5px; } -#woocommerce-product-data .woocommerce_options_panel p._subscription_trial_length_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_sign_up_fee_field, -#woocommerce-product-data .woocommerce_options_panel p._subscription_payment_sync_date_day_field { - clear: left; - padding-right: 0px !important; -} -.woocommerce_options_panel p._subscription_trial_length_field, -.woocommerce_options_panel p._subscription_trial_period_field, -.woocommerce_options_panel p._subscription_sign_up_fee_field { - margin-top: 0; -} -.woocommerce_options_panel p._subscription_trial_period_field img, -.woocommerce_options_panel p._subscription_sign_up_fee_field img, -.woocommerce_options_panel p._subscription_payment_sync_date_field img, -.woocommerce_options_panel p._subscription_payment_sync_date_month_field img { - padding-top: 0.7em; -} - .subscription_sync_week_month select.wc_input_subscription_payment_sync { min-width: 180px; } @@ -230,21 +193,19 @@ p._subscription_trial_length_field input, width: auto !important; } -._subscription_payment_sync_field img.help_tip { - padding-top: 8px; -} - .variable_subscription_sync p._subscription_payment_sync_field { padding-left: 0 !important; } -/* Variation Pricing Fields in WooCommerce 2.3 */ -.variable_subscription_pricing_2_3 .wcs_hidden_label { - display: none; +.wcs_hidden_label { + display: none !important; } + +/* Variation Pricing Fields in WooCommerce 2.3 */ .variable_subscription_pricing_2_3 .wc_input_subscription_price { max-width: 24%; clear: left; + float: left; } .variable_subscription_pricing_2_3 .wc_input_subscription_period_interval { max-width: 41%; @@ -264,12 +225,10 @@ p._subscription_trial_length_field input, .variable_subscription_pricing_2_3 .wc_input_subscription_trial_length { max-width: 48%; } +.variable_subscription_pricing_2_3 .variable_subscription_length, .variable_subscription_pricing_2_3 .variable_subscription_trial_sign_up { clear: both; } -.variable_subscription_pricing_2_3 p._subscription_length_field label { - display: inline-block; -} .variable_subscription_pricing_2_3 .wc_input_subscription_payment_sync_day { max-width: 13%; } @@ -294,6 +253,11 @@ p._subscription_trial_length_field input, float: right; } } +._subscription_limit_field .description { + display: block; + clear: both; + margin-left: 0px; +} /* Users Administration Screen */ .woocommerce_active_subscriber .active-subscriber:before { @@ -413,7 +377,8 @@ p._subscription_trial_length_field input, color: #AA0000; } -/* Related Orders Metabox on Edit Subscription/Order Admin Screen */ +/* Related Orders and Failed Payment Retries Metabox on Edit Subscription/Order Admin Screen */ +#renewal_payment_retries .inside, #subscription_renewal_orders .inside { margin: 0; padding: 0; @@ -480,6 +445,82 @@ p._subscription_trial_length_field input, border-bottom: none; } +/* WooCommerce Orders admin table */ +table.wp-list-table .column-subscription_relationship { + width: 48px; + text-align: center; +} + +table.wp-list-table span.normal_order { + color: #999; +} + +table.wp-list-table .subscription_head, +table.wp-list-table .subscription_parent_order, +table.wp-list-table .subscription_resubscribe_order, +table.wp-list-table .subscription_renewal_order { + display: block; + text-indent: -9999px; + position: relative; + height: 1em; + width: 1em; + margin: 0 auto; +} + +table.wp-list-table .subscription_head:after, +table.wp-list-table .subscription_parent_order:after { + font-family: WooCommerce; + content: "\e014"; +} + +table.wp-list-table .subscription_resubscribe_order:after { + font-family: WooCommerce; + content: "\e014"; + color: #999; +} +table.wp-list-table .subscription_renewal_order:after { + font-family: WooCommerce; + content: "\e031"; +} +table.wp-list-table .payment_retry:after { + font-family: WooCommerce; + content: "\e012"; +} + +table.wp-list-table .subscription_head:after, +table.wp-list-table .subscription_parent_order:after, +table.wp-list-table .subscription_resubscribe_order:after, +table.wp-list-table .subscription_renewal_order:after { + font-weight: 400; + margin: 0; + text-indent: 0; + position: absolute; + width: 100%; + height: 100%; + text-align: center; + line-height: 16px; + top: 0; + speak: none; + font-variant: normal; + text-transform: none; + -webkit-font-smoothing: antialiased; + left: 0; +} + +@media only screen and (max-width: 782px) { + table.wp-list-table .subscription_parent_order, + table.wp-list-table .subscription_resubscribe_order, + table.wp-list-table .subscription_renewal_order{ + margin: 0; + } +} + +@media only screen and (max-width: 782px) { + table.wp-list-table .column-subscription_relationship { + text-align: inherit; + } +} + /* Hide irrelevant sections on Edit Subscription screen */ body.post-type-shop_subscription .order_actions #actions optgroup[label='Resend order emails'], body.post-type-shop_subscription .add-items .description.tips, @@ -513,3 +554,6 @@ body.post-type-shop_subscription .add-items .button.refund-items { } } +span.product-type.variable-subscription:before { + content: "\e003" !important; +} diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css new file mode 100644 index 0000000..11e0cd6 --- /dev/null +++ b/assets/css/dashboard.css @@ -0,0 +1,16 @@ +/*------------------------------------------------------------------------------ + Subscriptions 2.1 Dashboard Stats +------------------------------------------------------------------------------*/ +#woocommerce_dashboard_status .wc_status_list li.signup-count a:before { + content: "\e02c"; + color: #5da5da; +} + +#woocommerce_dashboard_status .wc_status_list li.renewal-count a:before { + content: "\e02c"; + color: #f29ec4; +} + +#woocommerce_dashboard_status .wc_status_list li.signup-count { + border-right: 1px solid #ececec; +} diff --git a/assets/images/add-edit-subscription-screen.png b/assets/images/add-edit-subscription-screen.png deleted file mode 100644 index 183d79f6aaaaa82c81e2b74e4b90a77e2198cdd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40200 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

VF7iLh}XlwSIKF6dwZB$gIS?zX;jjv&3txS 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

!P-=iOQRFFPjLl?)+U-I@$=e5MD!>Ln^)9 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%0AT8PEFBh~(3g-9|2*Rzn;d-z<$LnyV=EOu4 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 mRc9};UaxAsn#}Oid%u=THM|B&iCKF7CDDG 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/J){NpsPl0E*_^vh>`b&f~=U_%ZooXZJ&IY6O}H zgG~}^T1MCWglWpv;p$LD2H)cw0N}QQe?5P^;-xchmP8MJ@-Tws7R%dX0|D_Mix|xu z7LM2lfZuv2Vk{F#5qUH0*$R~AeLQaE!i71E@H4n;QGJzNF&E+*?sPzqy70vxJQ%X6DFHAC(37sj2xZ zUUX)+E(_rvk&NF(-?y-`P#Lol480^j3lY6RZK%$oK($XCdYj?~0LWD{XJ4WG#Rrm! zC!rE@Yn$c5H`UmKza5s3E!UTAAM-?;^~L|G5uYkxuw@oD2c?DPDSt=Jrl(K`rsZt8 z(QG9{A)o;Gj{Kl}i+eVWDF9eF66^Dp(}hx@0Lyk|lt>WoD^^5HOrR5t6oX0_&`$-` zzsc2Dzb;q&ane1N-*2jI`Nk8eM+ha2(D;hjBjCX*%0d;WEA2$h&MgtbLy^KOB(l3Z&*Taae6O(%Wck#z0Vr$rdS05TXEKWXOyO z7a~3X%r^V2n)c5}9_{(yBsE%u@`_zdpU6X6m+fNqHPIXqzvDntRE7&2;FMvdt=-}J zzH?MsQo^#X7O7mS@SP<~>qYqI_c&q5N*IvOWEFQwd}_<%t>w#gfyTFmUlxQQ`z9Pa zD&^YzY_(XpoGUnECde3-B{($L1(tk*Ui!EF^!IZ!g*WSLV-`-VxWQLJ&6ZX+YVJ)k z^2?nvegHsCzV+tw7=$QUdlXDGJ)kz{(KKtrp>TCk88>o>@l4t&Moa4MXhOfyv=luIBJ|hY6 zA(0_sxhMmH zM^#(ouJ0xL6IE(8gk1?r7X71tLgOtAXKIz)eXujWD-0W<@-%mFP#^Ud=J$!nsIICr znJ?f2t?<~~wF+?(CXdZ6f|(t*^o9%Vp|>htPas$FOeKoRJ?d(k3GIW9E7b2EnA-Z{ zm+Ol)X9?oS3*jgN-PiMhy$;SrJhpm9n>l=YxVTZ7D^Sn!xh7KccS%)h*IVvuDjJC4KHgt^+;$wbg69fVo;B(>lsQroBAcG!sB9pQ z)F~>8hNx|=!}I;DLS*V(gspiJFHcT6i#OT(k=gxhXHQECrbvwu7gxD7LS3++z>&2m zvC|_c#*%WZTx^Xc3qRdSW_5Mh+OIBeF1O?zsIPEGoEjOyT^xKE@t@Np%z69Q z&RQJm?6YTP&r_eL2I5bhYQ*SZ?`r%;=j63yZr0kBRmbMCg_@k_OAzV&bFnjDvv`?q zEtTA|eqLLVpIEdMG~FZyeFlwaeW8}hy{|hHCv-|+t&7|^gbMG!DkvmOV>pV z8ec;VG8~8FoZb4@OyVNTkM`Z8X{S$9hQ62gf7vlja@T5lNI^~U*~{3qpk{rS_VcDE zu{s$-dsEB3y~}m7>@JVf!Cmw~VN`fiv*B;{MTMpombwOGIkWAf%*Jn*YmSz_v`v?h zCN@&a(dib=Kw`?2SoQCbhwzWrYkW2T{(!cJ3pd8Uo%z6A#mM}mRYWUvO_<(B{|qv$ z99s;aMx-5xzjFkJPaE zg}tX*vNLNh-Hb?Wu+g?0&E(&wE!AFi$B9OHovwF?2459z%OVgYXr$>XXJNaYZA}zr z%!vwn+q{2_mecNH6uWcIS#7j32)onx@Se6yeSiEd%4OZ%=~}CI+87jG(>hn&?c(5~ z1HN;1lnED&?y4$NL=x`ZhKF)dp-e^N2`86VU;3=@-PvM>w#(nk2*f88PiI>Et^$$| z5z~Uiq@PR%Y2IT1sc_R#dp@c&+0^t7oL8?=dZyr6hHs{!E<7Q*$jeu+qG(UxEz$!nNW*E+2Yj!TDNJtl*sUp&p*5(JJnA3pHc zHOw&6Fd^j?Y?2D)Qt@D+-t)lyLWGR)_INPiy|YM$lW5|?`gK7pAJME3W2P1AS@%Py zLV&dWhhbjck(NSHvjRqjv8DZV{?`aBl!fRb4Nu9 zrqoSV=b5rqWPjo&&uG}C=>f-8X=$n!A@X$7r|EYU)d+>8dIa zU%|>$i5Sn80+Oz!^O?D<&}yC+)Xvan#8PC|o}WpsMFStfloUNS;KusvhRM~ps8EB7 zjR1!UEoGGE2HVamrrwYRUvXg9t)%uFypoW7vY(;8k4a_LOC60@b7V{L^z zVZZD>{VI&5lJ%M7X>AD;JrCsGCW2BDg@+!6Gu6!;I3aUMG$r$zo?67KF2pqQe8*!V zgz!A9;7`~3l4V6|B|PDc*l8Q;RdcY5SjP zxn-0{w~s-d@NfgKiGez`4F@4%BtqDKbqV{sUSS}zzVuVm9?_m5)^5=HQK~+YX0Mch zD4#4rh4a69kIx!%8VOjuZWV@=>SeobE%=(|0BXl5qusL ziu=!13RV3+jRLL#35@q_`W3e*1m2`W^2u{YHwV_#Z=!Qwq$#{Fo(*&%ly0k~(4uG7*7?nz-51jL`akxFDW7zbA3Tl3YB< zl7sNo@ia{IlsjRFnVH%Da%bef1V*gruAKb*{N!ZpFp7S2S1|1C7;9f{RsAR|+?g-a zoyrv-a$V`|%@4J@J;U!$guFT9#E*MEgbN$$;nfjC@`i(Gc~; zR@BZJ9zTy25{OR-lKB5t|NQ?APWV5HUf$DRJTLkm36#WJ2R9En+N{2f8enaHf%=-V z=jAE>is(xf3KJ`Ymnf1b$N+_ETy8N^6uTcp#KffkCY74&D}lre`74zL|^~gGuL_U z2s;YY8{T&}Qo29A*leoOPth=mpt8;UAbH5irM1l3u{%<@yJb)Icpj{H1=-%#bT59Uf zPP;7)J$-RuVgD}tc|G*%0GyNE-QCbR2@=*fI`=Pw$C|2U58Xy7goR0-(^FFuS=9e4 zRC=Got|d(r*D7hZxviQ@$s{N!2sqQThzukpMN{j)@yVvPwstfn0y%cyZVud>h=?d6 zB4Xox1Uu~G#>_(3Y&^Qt^{YrV@K!@Z4D1etGarmE&CqY(z5y2e_*p=g!LCYdEjc-P ze0+RnW@c_qi=ZUPQ>J+%WLjPGP2=TM_}O<#8kAggbaZZRZX>xJ$%mDdmHK*~TI`~t zA~uA$rh5~~q_HEnh~F87xU3;#P_NNDgn;{PswExU&&-9$SYJ38RkiDtnmed=_V%{k z*B?tZT?YPx*y1nEK|)oEnHl~YA##b+bb^~xexFFb?xHcucj4pW78V!x!BW%H!`QXu zhM5r>FxzB*EL(LBrXV39-RJn|fB1+u8JRY5jOX_nuXA@xT!IBm(&QT&^EVr#gOs#1 zBx0RCJGCc{w|*U+Xt|%n!sE`P@2R(@)Yv-v*Z;DR+j_YlLaG+<9(4oeks)OVqQb(N z`eoz6Wr^(C2}Njs-&GEWwMazN8hu5%_l6mOBjRN2)8V5588Vxks1yBZPym30g(ihZ`!@G!3DuVv`5G1JAhJgO*%GL#_mTBRB#-k4X0n*pt3N5Bk?gmUAf%p`KA|GUe3UE{4P=>)Yh`FS2OFsmY*1CrNI{L#Tx-acuW>RG&TQ zk8WKykM;x3KuoVf2m1Nl*9mKvp-mTXXAx%};%VX`SL?d3!(q8#-P5+Xu>%v{a zJd>_jt4@#+OOUf|UgJUvO7~LugF760B;#(Hd=JeN%vO0r?oIZcpkNyHngc&}fC@4e z^ZH==&_mMctrZ-!M51uSGFgts2kuOgkAte6DoHL&g+8Z#`Q#_pOPXm&9fkuR$vLGE zmA}gz zUNqw&e(2CbX3N@Aj2N*jb?^wN)?+b+k4CJ4pDsOxsFKUIrJ#@w36j1}X5JqQ*)Kt_ z(Tj8LH|O+t^Z1eLtD1AY2!dCe5gUXA1Nlt_+NYP~NpjL>TO>AuaPQ(|3P7{BpllWT zH6+(=*JQRvYA*}CqJ1K*Wvfth5E{LH=K;PpGM!+e6* zQHVOd?^zyhKi`iPV`!yS@pkLbV5c<&(R{LRsZqkg z96C(MQZDqBz3xxBMv1A^Fbt7-(H9Uwi5A+5%g~F>$lnx+Ji#MA65O~%X5W5Xh~j=y zVl%=Fw@c-eai`kzD4QQWOR7dH&1gI@f?#!IH2R3Jo(Z0Ff>O-Y4&O05LD*V`vAS^r z$7VvbD!C6r1`&}(KyJTNQ(GKT9hqF77Lzia<~+}*gwWsMIn{&5{$02plZG?KqIGB6 zkg|BVeZwTWNu%V2`{63up%g4__E7rld&q<}by<9r(PIP+I9-VZk?7Q=YL(p|b-c>d zd~e~+;20^)-n;GY?I90^JkywHO1LQX6C&s%(;7ARK@1`!De+^am1wk?EVB%mG=&6& zw*~g<1^cl}3`?usxr&l45v>(Uw0bKd`Vr*YRwtXpe<3{1Z+f^-$N-EXj zN{SxYMf0fu#5kBJLR+m`q#;j(P2lRb$t#b(Zb38J=aCW`QO1HDGh7JQuTqS|hPy`z zTKQ4p;p3ZEva+#7x=Y35T2mafPuqUlj7+kM`@n+V&$_{zd>3xKX+C2lU`vE)szU4T zT%!kwq{kF4kQHB1UjC&6=@Jhi2369qDUY5Ke(|iGtA05?Gr4NY$cv_VQw}{A{N@%w z7!G{1Cb0uy>fm>dZd;xirSKMM8thGY&}bacU+292dv=+Eq&;pWQy*l3WrxPzUP%v| zrsa~47>Q>P0l;edzz1U>hYwixSj-Wls$^|dF`L>(-&G6n+*$ml>>`5UuRm0}Owu{S z5zE!Fw+uiTaXK3^Gf9-KUqJ2uN#N~8w&S=lKTL`$@9;=Kk=8fuyWezUV9`z^V7&1R zrNvhwRMy3hMPim}KD(xgv;&iBlcUK$e1#qBiL0J)=B94K#)hyiI-sS$<{D}eUD9jc z&^s!D@bI=JLsDNhPZp*_+>*CJF^zLF>v1Yc6rB}IBLP>h&x(5LA~0M*Df_CRV7X#c z5jV@IRp@Ja^tH2n=v#@;9-kIX^iF1B0i#+iwQCE`;G$kao&vfjj?=J5eYprduA4v{&BhW0s;?(#a>)f z!+IxgA}qh2{x6IgfGMP=cH6kTBVk`U@oHOr{b;&}7bET0LB<*)z~evTpi;-mQTRPU znhMbFhQJDbA=Pmm7k9?Waxax~Q&e34A^j^@6n>snM@t$%S z_vW?(P58wq97;Yn8HMwxDM!fO^{YLdUK~1z4195{^yGj6;#(H{Sg^cqT?Snm?l+il z)nO@!&TpJB1QmC8!4+`Y->M$+Q8gbRQ<{4wd4U@-$PaE~`|;uKi*fjMefFRy=6hON z6^oL!Qg${o{Meq;YQk4p6EbK>Og)hnaWtMgd=fL~I4=?RJ@ARX=uKT2u@Cdnr1x5O zuUm2*dI)VKc(LH4TVT|{fi9L!a+QW6GUr&aLhY#i5)5LQS` zP3^-9Rr8MMXoD(HQ#~fe!jX=$zrR01$w!V>i^!Dh>NWa40GG2PJMkdKlh|`r|C!=B zl4f*w>8%(YG-+lFg;`HePptUO)Uk1_YpU0J4al*8(j{5|OTl;Y6?!O5!dkX@p5c^*AU5}ns`gIlC#qY z-zC3&pJWnmx>piL(&A{MyB9tP9E4nQBJ~eEZ2H350!YHx zA4=hgzQ0Gme?NB2bc`oYk;~YR+BvdSg=TAr>)PMN^>ut=;*~!Fs>ZJ$Y`HLKON^IV zj5+T9Ua%DLNp1T+dy!!$M2<$kBAp7W9~To7b4gvcoqYC9a0)3U8Je~l2ExqGY1=n_ z`RNbT`9Hb8&D-*zcIf`hTXb~!0Gk$3sU0FP(nm9w`5uF*Gq$>#t>zX(EO9I+p?NjJbtw|S2fqKBKNw4 zn|QED!H7+hZ#~&rUo6l{wCGZz2e3<|%^QS|y`oa(v$128Xj4YC%FAUT83^Q2qfqAF zMBJ!Lwc)8eWq&oYVJVt7?@)RdH}hV=ckVPV%0tvB>eISn^uh#KNMatQ-hv3ABW(H0cUDoGDsvauyGK#FdXSuOWQRgY=ou z0+?v$FYng~wZiD&^j>@(m6(uod;=o19#TlxC4M1`zCWy%4*%I>cu8$T!QvAs5xwdp zi-DJ+^@EAcx~csMoil$24Z^^v%$*vFNdF@slP=|@Ke2uVz9Lt@&IqSu`M|)xBF?Z< zOSStCJb0Dz40tc7!~hChHvjpREyR_wTv9Un zB#it;zV(-MCipO-a;6VTpGZwzM*J?b)x{b%r!Pe@gAm|EmC8R!U%ZXJ)Y>hOjfHm* z=ynagf2Rf5l~!E3FNZ2F=3cSEcW=LB4f7B zQ%onG#z%|)L}ZUvK-XyQ{km!vpL^XY-9#eYTN;%dVlzy#&5d3kK}MOrS1TD}*dmZr zFZta_{gcR>l))4ZCzp`>B)b{089Li0MJCh=v^Tx3@&|4LqygcWb&-K&0W!x?U79_Z zm{%Ra`tb-T3S@l}93Lh08G;eJ>A9>vY#4P;p``5_=woB_e(6dq!2OPPf=BowQ{o*1 z0u5H$UGj)=5Whdo@Cjo&zt&1OE>0jRYl8naj*hv3Xjv4JPW{%!2QW=bON@O zcHgVD4u3#)WMpIjOmbdr^*mbx9=^YG1+odZz(4wTuEb&}o>jlz7W}JBr$WEc;ZL4a zl-J3U=h5$qj|-K6DF1>h$I@9d`5e(oI^1?g`=T%bD)oGQI2#v-;Q*l~?7nN1KVlF} zW+?|cBLpBBjd`3OE}K|3fAzin zCpYGy_A))SakE-nj`b?ZqvxxBh!uPRu!4-MqDIXY65Ns~u>sCfe-pW|iT|r_4m}^W zzF0{-&-?SL1{|Tf<1nAuL2}`z8VjNr--vZafdN&?@0Gi5g4l3Bc@tk>P8H)>^}@kN z!`}~2;qK3-boR5nu8C5ibn1cNeA663FYFF>b>)1COl445oO=1f0_p5a>+eI4gI))| zBahZg>Fqjf|F(dmk###(@{jvfE4JL(sxQP09`xZd31Z{mv3K3ffhZsqU*+H zA0jF_p<7$#Xo>{*`1U-+^_aSmmLbSvgxfZKZHvsG67TV~S@0q0|BZY`u>=VNhzD_J z2g1YyYr(sM>7P1f=xAt(R-ccx7nw~}zP%q&r$EU2GOp?nE44PPf9c3boY!>zYR@)E zprv;t`UP24ip3B)vG21Fp}q`zFH1^M7&#_UcxX{J7345{>%fP=`jxF_BC6jjliyYd z2#~xpwp(CWrKP89u))8r=@uDwH3VDM8d=z*93@{eZXAlc>q;?(_(Q6aNhCsY31$6d zD`rOsS*RM#AoLiwK14+5CvstaeLb$JxJJ8y;}H*0gMqCPWkQ>xeyFp4Ma*-4cQ*v~O;@{!q=qmM2?a$~ zMyAnuy;Bjw)))EeXr;wnPcK8IxGnJMHUgdCbhQnVks+7qfeYQ(uS($xVc2U33>9CnTdw^?#VArRZwXogZ4-6Qfpz9c=3lrZ@48N|L24byUChR+<`*p7}Pj(!f;N8qF> z#7-N=0ysJdy`YaFfYE_o91fT;5$Zj5nJ>jG(D8?^6$MHYC*!F(ItVM zv@~-yVm>POXR;DrVrtLN>@jIxZEx$TsJct@u{zt6d?euQl47FlaBZ_5X?Zux2(v%; z@N@7IQoNzyi;<=hFis_S_cIKkUu>LN&BcvTu00fS8ikx;A!YEuTu4sJu6)8)TQW}ll=u@WY2s3>rH;t>Su6`;(%Wwls0<^B6|a6#1V+wG`^Xbdvyg=k zNG#FjP(EwWrCbytIb$7dmWCxHQguQlIKEGExS|&12V#VpuUU3R!*+yzT@+v5qRmlE zg{T@l=2Ro`mnd&>J%7S(P}+VE*SosfQC+RZltzq!T&v6Tbl&CyZ;#WF*oY0gW>$}b zd4A1|7K1WI`ni5JJcrD|8x~w7mt%(*UJDhmTwUZLI)7qa*TBkwzT4DArMZ`jr44vF z6Pkdx#4P3-LixuAf7)~3<}nJ&PfV98Uk6qVC=Ov_Yti+fkOsb+{ zy+0mjp)%Rac@g^_FOB?rGw-t+`>#mv(e;x}`ofm`pQ+takx3p=mvU$c(IXS}^8m6BXpcuX zk3j3Z141tN8TN{V598IV0m+o~xd5a}1PV3}xzsHwAUr3&@gA*r1+RAo7UbuDj*SH* z7r50Q190_h6@oW!-e6&YdXZ9+lA!QOQ&W@f?#AXOC1eZ{5pfkfwvG-&1O$*U*48GR zdSXoSbZKh9X~lj*3DtcCA7^kOwG)PT9k{ z+S5UHr))S327`x(7pOZvIr*}G0TL_EFa8@nM_`6bX`^Ffie>Z2FJ1r`S5;LtZnE#c z5x(~R6*@2wb>@3b4Tp9ub!a3UX@1pF>bsv9!kjO?(PTpd8 zdUSNOx3|}W*o(qGy6fib?A&5VMoJntklEEGo=C}K=$Gf(vJsLF)^fp?+fIYYCeT)m zmjN!XM?|}S`fn6q@u0un@&xmc#IwD+C{b%=N?{h$NwgQ+V2qNp`$o+dU*IU%-_ccER7)k$|^$) zROS34(+6=(*3KZvhzJRRgV?mUx8Jujv#WzG>hHO<*fhvMV^keZ(bxWwfTw`ag#?y{ zZ9&7gdQC@Nx09K^Zm z{&Bb%)6OJ93$%UFvPL;)@0vh6Ndr%a4$J`2vztL8xbxqO$Y14X4H@fnhmhC~Nnr|M zd8FXe4Mp7uQ5`zBZv6I0T6&#)-Wgd*?5^Z&*@SDt514+nXkg_V28st<^0*T%mU^(H zj!PCqa6(~9()s9Y+lmC4nn7!ML_GtqwfLfDn&s}8>u5gFH^cGR4)<#wq@o9xHDXE! z!&1P4=X@fBB;Am(FL=wi4tEVi@-t(Zks3?2nABv{kq2unzH8l)gI95~JJ+Ctb=@l%>ymc~_Fl5&b~65e3CDSgwk-iM zGecpI=}FXqfH?fiv9wy+C=4VrhWQC3l%VFUU}#LPsSFXV`LU*2B@^qP!vjh(INq9D z?Xvm2ygcOaO(2SFCbMGV0?I?I z3`E&_z|{n}W^DIzD1m&v!~brxFDi}`9H*~JGGc~S8|t*sf_;;sp01Mv=dSX6VS=YI z=N>C3y0+WD;T7Nfw4a~;_7xKZ1_p8xTy}JK4dgxp9l1z*v}`to?B}^W48o?`%40lm zZnU=5q_YCuW7YvdjtH!r=Lt-7O{E-%Dk31Ht6br`u9A>Sw0gzuGh>^V(Il`;00* z;O0P=hL0!e@l0}aBGiH;WSQX`%fvt@V(;7YK{l)ee zgnejWz}MgZ4&Yn{O-{fsyHlkZK>HBYj9p)+jNnZ zmCY6QW)l`RXx3JQ19{pK|GjL8ld3(g4h^BioSo;DY+%f@vkBMr$kXs)(Q7hUdPNwT zRe#Xtn>4KxbVU1-xk|a4k%jZ8D9)l?IQS=DSM1f{R=H-HvCoyqM-*{=Rqx@{)YS8; zCkg#*r|k;e2NNmzyU@aug66(&5_I7UJs z^{A{H2`i9``!+qkDJrSZ4zbW7;RqAe=?gZ`?XG%2xJKc!9;~f~9EmI#JOB@jA(2e- z46DTvfK*M}x&#r>YN+X^p6W=2$^jTMNe;k}z>BL^fyZwUBMqVos9M)PnOr5M&7)D* zZs-Z(X$GmUL~d*?+C2E&R?j1^zjN|s^MgY}>+QZccU-6xA#e!)_scmsx>i?c z+C1g^n)eD%k>ZYZu0Lt}j#apa7>1{&rohopKmmtMU^c?S2z+Na z3R5qLP8@5%guaD?<(UOFlo3F#||NSV|vz z)ozI0>*+I_znj}-7!rD`$03)``9^{`On{a3)jE)4bJR};)|z|ptgruW2`}(xeh>@X!BfN@!6mC z_xF1Wwo;FxYp7lm6lLBvH!(>;0~8%w=a73%Uw0v(CULuhW$lfHCI= z!ybND82o$#_KzMvc9XB*mf)>FYj9iL*a<%SXerm)384oy8(XTi6(baIX7ItllkT+I z`h|pla6k##1WOvrNlvZ>s}^+M%MuS36BmEJ+#LgPiA2I)$3RhXcXz+QP`K?x>k6fT zy`Q-M{{4GcSQwZtcny9R381^n%S#On4G?(X=H_3gY!4-M{%)@l@%TV z!83#f^Z%iLzyx5$h^N*i$2$F^?E)+Dan5QnFNheMvtG-uy^acZ=OW=|7Qid6k0#|x z(&+gh7?JiB*9&P#9(R0%vyz2qaMzp~q7Wk|!_LGcc}ONO3k)fs*yV}`!{Ugze^;4w zIW9L&i9bVURmK0E_hB|U{Hd)Vby%$4+y+nlpddl)@t^=x9P07}_O!{_1kivid0;(Q z|9=;av3LCkqeQ+U*_+60GVKXt@4TmCWmT@wK|w*GK0kFKNAW&q{fzPm|*Ll-f>db?Z2=)pcz09PmQ<`dIa&mHNs#uZy86R}F zefJK2#nmvaeBNID2(F2;xupd-(HvqaT0q%#0A_${9lJX_sDDQZEuL-oDLlYBx>eIEzh*UijcKu(JM#{eT^628uCx zFw_+wM-X-suM05mwnnS5bUbDq!*(C_;@KXYKsVF5M*E77c!lq$OWWQPv;3eF07!cb$}!?X0X38eN7&H75>2m*e@OUxHm|=&P&o z4Wa*odV$#pB0`#_25osjw2eCKy_G2sF$e_#)F77n0n}O7$Fj8WH`|otUe@TY`4rXOzvn@nJ`kvNJ_n@I~x$>74 z2+e{5a`F%|0zeng7iIzEq@hu&TO|hc6>8b|a`**9)%_{dU{rY6qC(~< zul@Mxxhf?31Ns%2c!D)NO}TV`sm`H5fUpD*;TfIdhx@Fd8=+IXIi`EjL+{xzwP`;)pM zU6}^`i+fdg0pFdE|0a~SS?=g8;)8h$y)L!}0Hu1KEHwc5Le&4(u-ddI|9$M>7m_BA z!x^9eViIzgZuUmd1CJVD*E2-`^)PA$yl-d664)sG{7u2wH(M@u_!b!Q`#+hakS0xh zR$doNGg>H7rpOCedkXY(6_2oKxR}$aySb$d?^JV74hmSi31KNnJ-Dr0NXN6!sOWuI zb#F0rYFY*e%+=MEV0@W+!C)$*<{PVLz$)-r^?97v+JVkf1+*G4VfXz>BY>IyHy4%< zwU#5v0Cr*9>gkO@hjd~9B`Fs`I<;0~fFU;lL={kz&*Sys=H@0KPew+@MVUl78oj1p ztCa#Qu~f&XKS;jFG~eijMq}9)E5>b772u`DdkbX)mxcfzu*t^m=EnR_JXCSktyC2h z!p2~InBs&Ok;B7sCMG5w#<>uPE)Z8>24n&*ra*}X_es0JBMW$_>#pQ0VL3SU5R#IT zs*z!2WvzJp&cr4+^iLZY56!6QLA~=P(2r|}Yg{QKg$qXw`m9dO-Cf|mKWmM`Rw`EUbiZ{Q2z{Vnq$7fR>ZG z3X`|W6O85OG1pODP&eB<_I>h!9|kmJX2C;b>N9=K^wW?kV?QVbuMy;~%d&^je2Zkk z+34}4dqkYwxFg$A2ihfDB0#_U=b!Mxb9>;;VI9@2>OU{{m05$R&VK=Cn!t^EMKJD6&w_w_jYCoLU>=*1znFKViX6~+-QEiE&ZSy=Sm_s&fV<^CQL1h^B0}!w zXZ)E9l}oKxO`1*2sTNp_^%JpAOMaG=;f1lNzS%70x2P_ zO@g5#)RT*@!Hv|yyevCKjuty}#N6t2+lXEIw;~lh&Cj%P@?WDF-&55MV9;lbz5}2@ zvkOz&XA?7Ic%PMf14F}O7XiRC*M2Bxx^53Df8((O=nC*L0FU?MPe4F`H36psr^R60 zTVb!2X7Cbe+1({Nofa~!XN6>#Z#gOV(E-Qel0InPG?`9!9EG$t!>@TOlJ4Jp~ zO8=f2#prqc%`Sw&>eg6QAP%i{f@DbFb((HBTT{OUokHc={8UNxKM6ipqM1M{ zXwF0Y4+@o(lmrae(9FbSolg1Nr%#_ipW$P`w}53S?s4!7+&K8@q$!17l}ymh^6qq1 z9Cp9G+U5-;!LPTd|C(CPfN$~6yqj@oPtgjqxVZSpL+Gp09w0{(5$} zzY0^(y@=!7u3Y&qsN@Q{AL@9RJMCT|TG+`PKg>cVvs$16%*Ca)FD%AO+q^bsVl<1lx40ij zP9x_~_?@%5JZ>Ma%6kCx$L%TECi7Zi z-tyHt8)5JHbtMDqvbqm#Z2x4Has&@6da@0)Fx|Y9I@!_amH?Ib2E$!mM}7MPT%E-%1&3fwN-XUB2U=l;YeuSghQ z9a~o3+@xk>sNo!Rn?cVJ?abEHu;mUq!nWCxI1>XaM#Vg^*ZPH*W$R zJtHOM9;~DAzWIQDL^Zdt&(phXwR68(UXxyxTo6=wm)hIn5OA1E$q{KG_{YOtBCxLG zq;BUcKU>R{l41@h^IJwq8Ou`6)A?n1vAmF-sanBr#8$q`ZAQhte^y& zJ{LT-LKJR-QbS*s} zMc6w&wm(hVkm#`GG}=C-H++2ZtkCtiyU#N+dG=!6++A#=zWZI}J+;b%^tA?OqB1%m?P*A{-NtyV`y@R(eraI=1 zf2jBcIcb$q9Twi4tWvxTuq9vudY!GY;>QBb0{V2;_584(3v``Bz(ia<|1CRriJJFE zpP##=DQIhGY`F-4DrH-l)^!i$18kewnna$k-5=%UYG{}52rYDkhg?-~Y&6^y+Gg2y zEvaIZCN1$>R-N_)tRb#(7FkN0J6Q^Kf22<+P+ssZm6T$%o4qgtfgE})AgtG|MTCv* z6ol`$d7rI;cp+Vrz?=VUlzZ?3J?{gS+6AP0cm2}ke4{5E1vBXR-yO{qk>zAUStfudqt$)3XeS%KhYxoi=K-q_TlE^QcJ;Z!(=lSow?i?MF;Nn^~=qI`10z2G82(E}&wQ!& ze-i{;Jc>N1`9GEI=r?$E1ghE9{?zmJtZJ^P|KQzN4T;)jJhnvHJO~$-?kSUVZ_=*- zQ8nf@8^-k6Dj-n>DB2pDnn}m;HWWO1tsweQ=+v}nxyHONA|AK`i!|_XaYHh+hdw&P z8b9v#^Vb{0zq=u6IQ&!fals2q?C(Zv)zo?r(ZOF$mGM&|d=~r|5q;KGa@||=twBan zX{scpUH-GaI%|GLi}L$Pc8jM4oEXcshHv%$7CQ&9j@G#fW}GMK#sHfme($<*rBT8= z=s3M5O4F;mOH3_f-PpK*3i+osBcY~J0z9&rLc69Wlmv3#dXwe78~wWHudLSU;;&{9QnO6DxhA|N4Gw2gi@?W(A_zs*4lDbDHPbc6~5c$JFD7_CeOqJ_*!g^(mm4hPV><-=|mmHpK9>@jv*VX$Am z;s^#Ia5wBj5K@P7T@7deBgNgSFwH~>VCYqZ{qaN z^f1o%%z4fG-tVu;spaPUx|g$YoyTAs^^Qj%p)Y4xi&`?Om{dFKfj0$hV;V zt&1<{1j;6`HQC&ttE*}9&S(2&|1oP;KS2(E4V|%2|K=o8a#QWdAJA{38gn^BlwMbq!9(um& z|B)}CDfsSGG^+E->q&O`H%svIGIv6L4SpN!s8YFXF95n*i8CEs@vqh?ORvjst^8|Q z=VCC6*g75Zk%9#q8PshIFr}sdZ`ibyI$jS-pwrgBGJo%&+mXQpujA!9i)Z#=X!Tv4 z=UGRaPtWh{u9YcH&Ors>w#gOq*(iH!a{6y~sgI@-!%W?ECfq>W(Z_l0R0`#kZbvYy zTz{KRy`j`VvGxoa;IdDDB(C?oiMbwp`R^3*jNQ1_@}}3*gtYTUARKz$Pk$GGve;_X zhhoqre16o4h>`%kANheardwrlb9nkOq2MO?J!QaW+R3bP6`TLLt$q^mXpLt-5`7eLQ|pTp(X*y}Y_P z!Ze>%bW|F5jd&Rht3A4EP)wgNYWLV(s>nTA3BD}OHVK4Xv|73AI6fZlqpPBq#{qE` ze6}~TT|Biq1KES%yJJ?uyr3JQb*jmyLo|E+;?4eNy#r|$$OXZNQa2I78a;Z|ijRnHfr^I2T#oJF)`&#Vehti3*gj{7`-#R`}IXGt4CLgEnZ^Ox)=fQcG0x?N`LO_$_LLRlB&}ypk0pt;ER_qeo5OJb#?Nkws)`Rci(kVejZF0l7S@73jxK(^`hnrl zkNy~igyN6f_fK@hkz)BPX4l!=oCVQ&PmCupVRr)Hydvf z*4rEIiP%LHH1a`SV;P;|Xqz7uh!~&b{|@E?K+Ujz{KkU z#|11=FniK|zBF$*e#EkuQSZK|*%r+^+q@#Y-bVx!bOp}SzD+r0Wo1Rhf}`|Oy(UVk z_+a%_?3go<5uk&+3-MDa)&wB|Ea|-<^)Nplgbe|K&6laDpzua>h?^=2)qwTqC(JMq zMl^S+RiZ`w1=)=*Ne%-UaZu0o;C?9yQ|9hq%^A9seW>g=)sj5nieKD7v3=b%26bp^ z>R9Hi-86`*#P#FPzJ2gMqVp~pQ*d%5owtJ~SL6maI?7e$Fn0+~Wau`v71v zq6_4MFne+47sIWzaOdBgVgW9<`?+2xPppko*O<|e|)quS{5#GKI&l(4z#z58zF8ge|voD z1mUbG=P|LlcRblydpqR3@|Jw%rh`OvR-iJv&PBLs%38YNi>Dn~n(`azO z$#bPR{jnsyXf$ww~xU&diTihK66W3;&NUdMXZhbXkZB=>RQ{pO{ zf0`BN&KcUnJJ85A`m;biN`JVJ&HX6t`7Lm9n9zc(^Y2#MT@KfvLW*c{doYEd_(&pl zpyjfbx?wM7uEX=r)k#TDLBg)vSG$Pmg`jnz+9XD9i{<>U&J%_gx^i6%&x_N2kV?AW zj`Njg=S>>|5bGan{+HLiH_LoA#^ z-p1q)=xp_m?Q)R&9xIR!f7&OG2wok}Gi~pch{p#7Uq~BrTF?^d2LB6qY7#f` zNiFs{nNa_@9{k)vJGK_+y_Kla@SfIg==SZuhhk=AYqQ8X=cd3`$EPMns;rp_`fs_qTzb|Ig;GjD_3Vx>NyfL6WO zo4uN;mRordZH@4>Jj*=a<+XY^ih=sqng2YvL*7SF4k1FMDrUxaGG6zT=b@MKQs6gE zdyERzUGnWO`%8@Y=+xk(Cf>B#A7AMQj=Y}uQDeCqTQ1=vmO!b)U$xpisQXZJ z+P^fDKi7VV(5QGH<#hZ?Y}k3%g?73BuyVxO z!yl=FB0iwo;Jw;QO{yYifyl3We}8;!*ySVWup{M=TheY+N~6o~vAZ^)`JUf7S?4}? z&>hm>oOb@!xD*0g5c1h|cPi)@Oq4Y0XZhmca4DnlQ@g*jcu^Vm$B7ytQO&y%mxHb(Jq)alR2TOu4< zKK&I(OZaAclGOznW#CeX@ER^MF60Ho#{>UsFM-LJ1Ywc-(_3arA4j3dR^qW6_mD4~ zhl{RvYi@t~;m5wwt6+So^1e?wVBYDIk(!btyS>g6p}b$O-&}wnU+MfDe0{M4*p-?O zL9LVD$)3Eq9|mVU?>s9ODWsPlCWqM% z!zeTLX&g=FkNs~|m|Y;vb=qHE&qK$p=gE{f%$;~D zapglLnaHY$78u~lSjiFaY4a}|EwG^3r^vl?0RF4IF`!Dz93v=PJ6T%F_zxSKhA@=+ zK`-fIYa|Oa=exSPZm+LFb3RME-o;ZcaJ6Q9d>pvg5wgu6`YUp^f_dB^hv$#Nqho^vJo*3256=R z(gWEl^-1*ee1j}2u?FlCvLYOEcGS_pu2=q(pE+24RSKASzX7k-+Z6HahPQj6Kf@pJ zfsfRp#EvX)YM1>9e$U6WMj*?s%k^*Q-u@sjNe|<}BB%`_V#rO_qo%Tp zi`tF#DFsoI4?}4}5|I=Opfe~U0tW*xa1%A^*jCR0wdhNF36qFVe}E4H_}W4H0QkW> zIy%68w_p#DbM2l>Nl5{(!qjrzRZAT8PE8T@(g&cRem>>%EFDi6$RQ^_+Y`jA6arfl z(B1$Wak0v380RFe+UQayDr-^(2X5-QyaqwV# zd2nb;OG<|I){yD2hm}!e+CjYQ@$A6e%^v4zmcPG7?7?h>-bT@N&_j1pjg2aes;kMI zQVP;+#&QEYfuc*e;kt{6vrv?=oX_*z94fPqpkv@r+tmx({`!Rr=f&>R zNs=17zNvKPLtVxn>?*|zQQn9BX806aP2xBj#uC5qgrc{B+BrM+}w&qIAnWcMP2%H!1Z%(~tC{w$n5)50>roJt$g44D#KG;Vyr+Cx+{E71#k4u2hz9%lep@#*lFOni+@PshllX@_i$6l^FBr5D4@b-6yrktnl1;J6>rS%Y zWgL*6sxlE@x@YANzlMJ4Xg?wJ3M&51xv?MdB3-2R_O_**CN#qB$@O*6lbae#p$gXG zEAE1qB5+@lMWjWNAG-0A7W7tABs&r=Xx##Vn3( z4m?}InsYW@Ms7~T(nii-bs1jRBK)Ev|6?es5dXz7b~Nc11&neqIT?`~>t}$?0uRT* zF!i*edcIsKXJ?AoWu{`W!Na6A+S#ko`cfE_@4hD>J#z2nAoS2>|IXwx&3Sk6!Teza zEt2Du@2lu))xs>qN`p3~FSN<)deavB!D)S^@ri$t;Sf5;29tNWYWZ((;Y9~%OiUV!Mvg$kSJIW)t(AF?jcPaGj?);Fyw1|Cq`f&3}=7ha}oHIwpw45gCAC+Ifw z`YZi8Zx@R;3kT(DJa#XNokAerZYOOktZ)lBsCAm0m+BkgI!zAT)$Kw%=QxKfI)eH} z53|UFoBmtV$aF7~1R|xZ)kO3d2^VW}ilxrPFXW>Yh%Ix?rYnQF&Nw`Y%byO8gt2S* zM(mftBwnbIDNTCjky9idbs-BV--QUC7bhgt2h~@rO(=c}VX;QC6Ga?*y#$h2=UPQ`&67_2%P(?Wk z3CFYn%?q!3WT=_T2oz;*3QT{!zZW0&8y`k&fk|J0)b(`-f2zNfm;;;m&Ul|SL(rG5 zFDWX}wVW7Kju7Q{4kXf8N%G4&g*q`UtDTpYB(ESB-3gjBHdkAxhM-q?I*>32A*;i` zZ5S__sBydHCui;Yq4YeUf2ylqWuK;4*QZhb{3XP4bTt{Ca}*1Cc30S0^ypsfyCfGKSHt=-XY!CJNvsBWN&c}>Tiq%AEE zz1Qg39fJG(DS zb}YIq%HR~S8hnS3A8P{o-vd28r88DQn|cTq@1TkR0pcm|`y0?Zmjz8oP|0RgEopaC zEK<0l>}~r+{q+da@sj|Q~xn8(d!DQ0hzsp&=7snf&{MUfPhnXubN3P%aP%fo@}0 z^cb*Tf&3ldh6DqDN(vd-A7-$feSLVL9iT_??}PKwz3YG`hud;e8f;{5Ed3Zj2!ReO z=u-g0S3OWFf=YZNC`MFTOsuTSHr0ssie>M)2)rLqJ8mxR{Kgnd5H9{%{h`|f_%DH& z{LPy;(|$l|eR_N>Plvy_xG1UL)r5LM4NyBSE>#02eLX!u+43~R45}o>($v&!9>w^+ zQ%#Rs&K8?xxg{$!uSvvprC`v=V#0CoN7Csg^ZePtk;{wT3$_$0MPF?5?`o=gOCGhy zU=56D&>KH$@%IQ%<1t+KLzyc7I^Y1~PjlY6cAY%NK7(woh1owxS)CupjTWAk`4U=m zS8-M2nc6BONR<&^t!BuaW%hApESt<<`;T%y%H!|Erp6|YrQKHFZpFBckMh^uvzzO6 zvg)`$FT4t61-1NY;&z1`jeY8>1hq4jyfKZXmzJ?b?#^*#dvhwZgPbGOkz zTTJ!3m3!{fMa^<2vky-zeK0#Zo?Zj0N`Z3nATy)zF4cv+2Yx(_N%jV3b+`C=K^&)} z{=P;P48as!`fK_Mtv}Jy3ekwRVpEPqT zi%PPwo2KT#8T&2DI*F3@!o$g8_+2mU`azt~CLUR5&3Ko2K*R@gwbeA{@2?DTDJ4{F zq@as`6he$RD#i4PG{qdkC7BYwh!yc29+z9vMjYHPU$tbR$?1lL%MSh}9{<9s{vj$- zJZJc-TZjxO)$B{fGS9wARi1N|I5|wAHmBRof+a40=qJJrO8EuYckQ>_hF`EN2P_79 zC%?A$%aEv#EjZJvkmBR+Y-TwH_jf$)*ROoVBwjzW3;^DXz*n?kT&Ag>tH^5l1;g;d zv$Tc&*DZfslMRn|#3ygR9=dXKzREAg^nGs`*);cDLSi_HA8=ED1;Ov#ZsZ#KnTw38 z31xPWmFQb@*=M3rcQV&0H?i*py^5hbmm5)oc%2nh0l{&2JWT5kK_8||Os54m zhb)x|YEWJ>$CS|kqco4&e%hOJ-9r(R?UP!@TufW-K8chVx9byI_<>M`*QKfM!3^X= z-oi>&-fy61Cd?s3gC-__UD)SXis^D#QW?u%>|L1#Uug%lT7X(MCqcp&5*(Q@NgbGX z3^`TkQFC`U@as4rr!<%?%0_7gmvu^gSmc!i=opUtCVu5YfMTt8Jg&4FfSXH+P)XS+nJSw|BH zqyqF1AF=6#YkiNBjt!SYeLZ5fwdkF!N>CxSe=P)MV80c=R(|yKEu7+W|hD==rvlIeu=1Y+1F7pC>Ts}I!+K_ zO`9p-3@X;$ljWUDRbW}49D-8_dhXk_mV1a%IE4FTfA489>R{<&7sYba_cnpD(|%=A zx#~@nF!Gl*BrHNyoh!$(IeS4NsJD`#(GFT8Fye(E<2>_0{g=mbvcIp7 zQCJw+8^;JbsmzBu4^xqVeS#6Vq)D~a19uK~Xz8Qspkc?;eAPuJTi^P|!OkFbdhhS7 z5w2`+?DJP5q2wLlgaMv3;1Hsl3a)&V69trD4Gn_x?6W|NCZ8q#PlN-sW_UEx#6Y$S zM$)b(jxbVQEZ9;TD2#(urV!{G1O1#5Oh+3w1(b^42>BzPeA^?X3?}LBtDdn^^L||| z5qAFK@u-s#LDC0Q|3^CY8pS-sm~_&gXE+E)8r=78Y3< znVi-gs%Sbuwcz2IG%0u99yMNS_5)8y1|*CM^RdndasmC;9}t8WWF%7zjH(AyFkMgy zk6uA}!hlhII)w|CwQ8(&K+jq^%kU29%+WS+UwTRKh%gEmhZaJ>YIv!}P$Z|K0+6V7 z&fTrb^kftOH0>tK?5_j;xy{~N3}cnfL|OdF(xJ?A%Hp}|+XT+M2;12*7s=`!EtOwV z7KP^;U9aC8M*L_?&I{xrzrF4WtMU(eK_<`u%|mWlb6SqOnNAErK|{y+AXy9;jqa9J zoJ_WSuZhyN?k?u!5Sqt}37m)n1%FOsL`eMuQ>RvMqU1(JGV@JrQBi;Y-smXNle6>K z_u)C)uR>m-)AyKD6XMj`^LXjYN0-*nRS#zYvJYLlC5m0Q*~aWjDr6RyJVPU>Oae6DMo zSzQ-R4>p^#RN6OjVJYLEYfBj7r5AflKEft#a9JsrP<1&s@ z3o={EZM-Svce;MRk$E@&SX)@Ns`GSsIxIj;%%qd)8WpX=0)b?dTjA8a+~+^pukyJT zaj8swm1^QB70=Qq|EUS8^tLhSs;;Gz6K`AVzo9Y zl=*xwO@>j`+ih(x=I@}k$Hk%MhF4(atD{LU?J<>0M-JxWfN5)brQShewL8zVsonv0 zk13mlla|e?Q_)KPaBVh6*@tC+_X_iwa?7Cq;@;o7skm#D4HV#uaTVwwbhT1W-W}{5 zVDMgVBEtf&COA!s69w*r#;^^TcLHUoEUx-kbokwlreAq~%xyq}r%oRq*E>!&J)Gl& zGUbaU#4|`8WaYsR1Y9_8*MHn*33wxXE{Y~(l=Hmt;%4PCITF^^H*(^0^SX|)?$vQ^ zw0zPMe;aWoe`QkOHslD2<_vZs^p{dC^4Q+;Z?jow1l^^z%~66))Ev&)UIjI-J#|;I zQVsHMtE+r`UjD`Ndx6`Nx{y<+r{=H3lgdoWOKdTT*&Oy_-`HM|oeyd*Hz|De_LkMJ z>e22)++O6k_eqHZ5k#{N)2=MoI|z{DWqoly;-| zXSjv%mu{6*n#MZpbV0|P>=8qtJK{C$Y~98SY#gbzemSNsV87Pf;ss9&WBF+{-}o?$ z&S}c5U24%$P`m$D`Kf(1HpR?kS7{Ko;#fOYNRNt|My&1*9kXW09Oe)ng^(-py`ZA5 zniY|GyM|a|vWDqo2cpSsf2G5+I{gGfp=gudWXHN}UPs?OH8p1t*656Etrd}-|2ZkO z)3gW~E_zx{$gEjwF;a6e(C|D>YvFbPn|2UES3&3R<<-8^dPNJdT@Z$(cgbq^r^1@< z%oa|#1zafaS5>}iEpH#faAx*FdCfi9KLsmDd&6!^x`U>Cy4T)-Cfdw%eRA}Uw)$|v z)q$~Yx_j##j2$_8&&X@LAWdha0m;$1pcGd&q@{hz-TY+W=8 z`QN`=dOT&E_;pval^le9XAeuHwY!-v5AqiFIIwDndpc!9qAt{|X;V%ZzhQ(=M1qmD z4dZ;rK+UO+d4pT{$*335VRI4gcDyv9r{`GKv*pU_Kf_vK8Uyh{U9vjD`d7`u``?AK zsR~LqtD_mD6cOxK^;;nPh((fCHrg*-koK@n;Mm1#a5#*eBniD^o6nxw#$!bYI@YSmGZt;{3XzySg=bN&$Jbcm&x@#z%ip=w;Py@YW2g}C9 zL}CEeo3L0mHHiDv_hwC4y;$X4;oBTCWy)w~f0TTKzdz$SXktL&n2H|Fo1x2|B)oIm zDf2ZBPIYTx^p%8mPvgN@-Vm@@fcpOQpU-Fj?uuGpTMM1o0cvt^RNPyCpo3nP7lEf( zv3Q2ka;cK*>D~Gd9oW#o06}O6Z~`kQ;CF@16vJ;0>8t}`>_GAhM&vJ% z9}6PYm;ij@pQ?2|Fd#sgaDkSX&30j9KfP&&ZvO19`jtP4D9@IF@xiG1>Y|m>+w9FH z2qeurR)^~1B|$3R(Xr-)C6@Y~^Pkl7lyp>t4{hjY@k`%(g%iFk5aX2pJO9NWI9wsvDwtFg|px`cB7)*X3; zDi(?D&0cJ;mwMr7!kQ`q`IK;x+O|jxN0tjcjuFdYPXy62ttlua8=e;QAL z_De%6b;K;yWuUEGBB$lfGz;_NWX#0N`Ih#9TZ;FNR@cFSVKakwH|0Ggru{Y(!(97% zlPjKzgoaG4mCaNP7$NF>^@B#k>+GGQFx@8CeGBg|4k;h$Us%jmJEtam56>L^Mdg)N zI-SXCukrBHd-kkK!Q&4-{BOGv`w^C8sFiqQ$?NiIJyz}$h5k>PX9sgIv2!-_$<(=0 zxf3hxS!eQTB#Z>gF*WPPN~RLdldW;CvFz+`eLWL-cyE7liFe7Gb`9L@*dhy8T%EsE z5?zk3SWQ7?7An6n^>_0xd!z0pPU`&aL~B5Dld$K`O|2pAg^lieNJnvEinQ^0l!pGm z?gSZ|w@#N%aRUY(3)%GbVjy+|(jIv?p@;yz{;{rl7qYr#rE9M3EAbBlH_n=k>?T{o zosS|EMZ7AFE^dZg$oL>Dmk3$UN|%dY{=5eSl7;8n)0UEm*)aA}{)Ug_BE@vK?SE3| zst@Kpj;^30-hvIA^{}SfWf%9~YD~*(8iSpQGE^+|GEJ|6u7%ya2#Q$`kp&Bkg0V8Gwhiy!C;SL~wa5sW9crO^ z$nntWObSoFd(5nS^qFO8j~N3UAX7;(()T13R6Yt1dU3b_Q{ErHh3`MO_az{Zc6;ps zV|m_po_$p?7fR&*2@1-pU=AxTO=~8}Q~{;c;8+fgFnf~qZ(qGirS`=9G`Khew+Xc| zb*}pS!oto3Oup|l=YALd-9SM->HYJIiJvm&m)I0YgTB^|K3*@^rG(JxLmk26+sf=S z!Q|fh5?!S%7aUl%6}dXBPQzTX&hg?_2;qG?a)6R2OLp&lNCYys-g_~!OVF-Z$(Abj z5#uqganug{jy}2?x(UH7?ZG!8h)Z3%XWn z*E1K|w6ZCJu1mYv@ivQ>T?1My6^8ANMRJnUA-k0~QXz6_QiiX7+s?jKgt`l@vsH`m5%FBglB?dIwnu)H zY8w;+DS5<2`0OU=aeR0jh7hkZo3@|SbC3tugGfU-+5Gil?>gck&E}cSa2BGuS|>Et zeaieL!AOqR3to?nO`zXcY})Pm?2~eRdW78H-GsS6ROew`T4*E47IFg8%@JvD(Y%|+ z^JV66I6I#W9z4`#LqbMBAK(xZQ*5nn9=;;p%2RMd-VUe~s#vf0#{C;5g*{zAer)Li z_P~odTWktJS0H8*xj!2Nf+p|1=~7+qYh&X@YuT14s^b{F?w zoqu@*e-LP40{5>$DW8y#7Z`kNXz@)Q?O*Lo_CC5Su$cvG%v>4ZO27Y$$zwfx)g5IxkEWn@$fk2`qpX8;)rAl|W`{U}9VWCB^H>*Dl zX^%aRlwbb&4XR|pk(8|fZPAPRlGD=C0*a@A>iMVsg^HtrwqRmZH zQ`1n<%#4iJ;o_&&5EzwdE|7)^3kyHX2R8c=Zq*EW3yS5R)bCpSgC!#Y^8+0n{rK|I zr}896XJ9eqx-ZExK@M5t*&BtbGgHk%S??wyr{35X%RR>`(g4xB9nF2?P}!l;xZ7-Ii>J3aySg?hwY{PrSk zU!{h1_W8yEn^+CK=Q~G_X9z-lDnSW_@;3uN% znwG8KU(`qH4%Ir^Nuv~z47|{Ums?%Ti!sJS%m`bF710{mZM$mcx-LA~Y(6Y}I8KKn zy-!w9oKr7WH@z!vhx&-Tb$PQ(1q_RZGhcCeUs;Cpzet|WGHJ%RR6W0`r^Oq!C7Uh3 zStt$vR1;(RP~$03*yd|)3BN)17te3$szQoEFQp&ek;VueI!MtHuxxJ*T)C?OicM1z zA%T94vqiZn1&qVH8yC)+t#}I%+=8dUac_+yO`=PL4RgD zf*kl0L+fm%RV{m@t9)L8p%XfL_ZQ z@hX%MUcHja`#Z4ji{mQpVV*I;bnL(^R$7zUV8cx4;`Yp^EWMk($EBhRC6_hSbHa(- z7G|NdEe4KXq@~@hN(*F$s(E~F253nMok{}FgFSXB6cb&dVB=wO@ z-&QvH+2q<~6%*-bp`venIUg-gd7_(G1sRX^1_(gvlp~qXk7llU~k-D`U9 zT9H=vV4lk_1Ta$uU zVkAKldXe5JT|;TrP91km{&kb+?m1tjEFi9y^WQIdn6$XoiX-IT*aX;@Zk8a1hFG4P zPgH~G-Z1aHx!v=^o(kbNFZi)Y-@CPUquX*lQN?TzQK)X} zY{CI6;u?+1a>05fGp8_t`8P*}t&v_-DW7^+d&AkJ_+bpkcka z$5FLEN$@t+ukyS4%~*E5DvX+-@B0qKdvhPsDMz{peboCWUlT%ke$cvIPAlWqSPCo8 z=VIZWDmb&{&};rhKv|R`0u@_eW7SO$KB8gPglwI6CfmB0<SaxL=`JhR5+W_CT0>=j>p?v^gV8T;c^Ef{lT~dB;WLX?zCww8=MUE=j z#ntgDn7&N{ayZYY0Pxi1^NehN<+~o)HqBfP@LB}GC3~TZ`bT91K-tCpM{cez&0w`W z`<*ts>O*)nNFlB9TwKA~C%us*Hk97M8(urF4uo_6J++kgZt$A-wQ!zu-kGV=MIaY4 zEdp=My^_Tztw)Q$1}&Z=g>9!r=*s4jQ6#WP#%sO8qu>U71(UXzYB!6s#(f*-g`{Ru z^{MeX7MIU0=Dhkr=|Huge1V3nEIWV3`7AJ!rzlMz$ERMyz);Fl%RwQn)-4ZtSiJDp z>bRf9S=Xqxr%gawx8b5qCK(mmTv=PApzo{fSI*dihI(hxdZ&egb&RgbQx}YJNx@IQ z#j1ALGYmsJZN6vS!g1S?HX4YfrK7)WA)-5WcM00zf)?ZXpx^h;!V8L{`BTUaB3)?) z|DG6H0Cv~}3s0bOJ^+nJUaM&~;HLy&0%S5er&BR~3QNGJN7!>V)sE5!Tr=&s=v`qZ zDjwOKBQ>Erm~j86riHpc0p}^ zZ?l8Dz*q!KqI?wuk5l$~n?BZlN|ILj_D!#Rrr)Hz!{E(zGz7&V-_-{`y%Nkyn ze{CdZrxP>ukA!`r17QPz(Jm{gr}w(IH5&wtP*abPNHWB!XrKM{JZl8pR*%bre;@{6 z#myhve*XM;0=M*W`f>FyOAPt}3(G zmT`db7>tb|<|HCGc-W#6d;&=207D`ekj>4_LDv$PXF=o%@Go~eb@?p-K!vZbFBn|k zjXj{eKgTvlIBw0tu#hg-gZrcqoB2lf-91X(;msfJSux$hzAe;RyC<0Xj zuNEo;ZZUqV^Scn=^+eqBQtI#>?HA}TxS8g+zbQtI)HvNP;oM{qtn<3>TtB_V_AK@6 zO|)UY*W$3+0HvUr#yQ+db9D7JWRiZCm&c@HI_%RWi}zXC39s4`?K_ob(dI$+SR9)V8({& zEH&}V&0UmhXSl@j@?v0z_o^?+vCe#6(}i*vYI^As{@F`ZT0tD67GgF>agTvIj3JEj8 z*d0YyE?IDEI&HC8^o~Q{qE#0hNU6WI7P#~@9nF`@>cplHaz3cXLv0kQ(D%Yl@Nzml z(g>eDr{J^bkKM)-k4zPE+ewta_oy)c_W7iYpJCyilzUg$Y-@{swM#lp*!ZH~Elc8s z6(UpR2jZ*S85KOkH#qkm6*HC3e5E3ZvlEMSvUtpLAQ?WHg3IF6J)tCZuBu>lmo_2poCP*g zqkIW2t7JmPJ9{(b8w0M8lQo^j*{Txqm0WLgb!uk}pJGLrH;M-+dvzjYie2TYJ2|rt zEE{jmcIPU!L%W~l+{JCOZ4gdYNWq0ai$|vLyDeT_E1JrtaND2x>cFbaw|37HFgBL) z7V9*p-el!U|7JHFO+anj4+$3Qy;r|q){wMbpljC`G|b;n2ll$XX~j- zFHm9^Z}UZ5|hl_nF+S1rGp&^g&^r-+uBt=OIL>CFbu4NK;>KIoTvD}lK)Ri&8q zx;kO>LC|ZrYUku890PB#5m7p7O1ZF!*IYiJBRtl7d^=WroQF}d?a>jKhY zzC%CSnY6-ctX?xTKlnpVFlTO#uv~w)EPYk}II`(n0J1m#_iH3h8;xArd-K+%Xj>;U zHK8Tyj|$yFh1_Oys{?PcB*I9>^EAud_5Hks-*E3tSWT2#&hZRbBIDYMFHT{IvN=uL zCQgT&_G`sFxfFh5*M}zUIc^M$r=)y&3pj)ddB#B(3m)hBl!SX(H-)oJ^_^K7eUs$; z7go3KK}avu25y6;-PBo$yL;)@nIxIr)v*ReSV?1jWf9Rf%${vAfaJ?VH_eOL%XC5G zi+T(iSu#$Gy`vVdTOMnT&+DyT&UWQ23xSwvY+keN=wLaP_TKBrS7(4E=(>hwP1%o| zPwyv-=PW!}!prs{by04E?-#WpV z36ItE5pc@_1qw;p9DrN^{Ys^NTOe2r9s@T&5sTIpSnmX4Q&NzS+*H@1`XsX%vZACg zQo{kxTC?AT1~1u~$HY+KX-qFSM|}V^aiBe9ufN~QAV>R8LI^%tS0f!m@S1Z_+oNnP z4dg>YhMkx<5U?f$4u72*yEk6%|L=brfKcY2EeCK2fB|@8Fg5ff8XTIVlM{|4X@H)| z5BzRGo1ZH=v8!FepEJtO%A(i$x%em_&SgeSdCG zTUCKg?da@ucXI>0<->_a7jH$d$OV5#hK2o5q~3^<+Tj+ zaCdiib-kOr$&Ih)6W!Atd4yy5^W--pf$I2grCznCL_}X0>-xVf6W~s4RZa^1=C&qZ zg7(vWH9kE$ri=7b>W9d+uWRDf78(;6Ej9K=6O~Fcc;xgE8iR27ae39X_l;#xMY=u> zXZ3XDmBtvq0lP-F2T48y0HZ8!_{e8}#MQLd~;x_<(TTf*+XmawJ z@?LfF%EX?aA*{?P?&n0NYKCgkmL%gZ(<#*s2by2^9$)AR{$3{3GI=={-?1itG&b&u zP#)EJ2QBJ48ON2<8H_Gy)uMR=}^(fl*0LOIcfAqe}2RNnhjf952nW5 zW)$;(*ZW*aox#w7#`nJm8oP8F)cdRILknC1b-=PG2O zsECKkBbuQtB%3O^gCW5V70Auf`@y|fjzJqd$LAQP4jhB%h&akp6Juqy zCF&EDBa6yei^|Mr`hbN6@}Vp$|IOm&stN2L%qph}jK5L*a8E<|_`PZcr=v zCj^K4JOHP6Bnfu`nD_yn1_igpIPiW4#kTy<0Zt(ZFjjzGgauwQo-cpca4P$Nya%?j zy~D%EcAfjFXho6@u+{rF}aPUM?wtY?c?P`#25jiz8=(M=I*Gbb9f@+AF zS^k7YIJkv`{NenojL!t)zd?cxD*{^zz`~%{+y@X?9%oyA07)3^zn2O(=3(IE=mZvS z(4a|4O(mzG0Jt=6pj=m#`URcV`Psn-%>b>CvY^1g8xWp$bK~ye@zxdz|6=q&>+7+K zT%Gc|zYqBe_o;PDf`585UH0(lo9k5mrN#sLA=RP0ni_xUS7*c7(Y&+NzA03rB5@_J2LittGNnx0BFZ(v(Vl94w@!F=5hbk`6^Ziy0+Bf3S}eez?&jtO657Db z5lke3v4^yj}Dh+_lS9dN9GpY9(QN3sx*xH=KQZSc>{ivlE$o9pY~-qgtGUmn_| ztcnW<9<4q7ews~M>tj?j0sE>`*v@{e^k-p~_5O^Fod0EBfgmO;9uE%>UbErmt}dYA z69Dmjy*)i|GQZ}Gs`gmf+amzN)e?NQAPBE-ZG)D5BlD6=hH_PBU0w%lQ z>S6($g?f4!8JG_NuL;?slj|dsfyOmi`gNBNbAEQ3@T2Gnizh*7_2{Z3&yReb_Flm7 zEwFQf#98DSjdA@L9zQ$s877p>0WBfws%WhUNzMi0UL7sQck6u6Ux1ucF2IbH^rbi| zUsT~0-g|1Q_l9J6Gtx9rg^+4G^Rzp;o3JPDYfekQ<;n6YW~}mEBcv|@{0)$_k_Sw< zNR~4Q2?>Er0~Eb>4ngD=V005PzcI4mNWv5Z`C&EP&q$x;TYkTz{8=_;4UM&tA!=I5 zXW8i)#?fIXrw}7>YzmTjbuUQ_0Jp%D2s&Hu(rlJCx*xgCdAj?dEcA1G<9AmW|%S17_1FKfiMzOn{BVf8GjxSs`MzJVL zQ--FKxP;3ftc5j*(Uv1AYFM8m2_PZ}WK6?af&kV*0UAr`FCioKzo;}N1_HKmi^`gg z9zfu=L=l97Z)jZr)m1}bK#Y*VEj2ah)9+p$C3cznPhHDFc1Nv0t+y{+}}8pF+4>DzRYb#<*udc zTOwjNv^m~`*aj77mI3qp86N%Zz+7p4kh(b{DCe-OuXED%Wu)>8nGBi=l< zus~kfZ$C!84t;wlw&(Oa+ktd*tzWv}FEp|JO&Mpj_S#EzCY4U9ch94P@z|mG5S|u~ zcOrO1v1Mh?SM9cN{Aqa!{2V{jd>~3T@wjN8E$N zZEUH6&BoIBkwhV)8pTyLHEN(sdcEFp53P6sWN9z^H&NnAx?{Uwz<-J^qyXh&U?>1` zVK7R9lK@ON_OJkzZIPUghEiWPJi!61L7D} zY2K4XBqk>Qg8%{g(8#}wtC0KE(Lc=CHp&C%1Iowi&Atas?wYdzA4)-2U-*+NVSfG_ zFr@&9pu$X6&(nOeny~0u$o7J<+1UpI|AMgBCmxWGMW0qg0HF-5*)I4fqQ?fnmf+Y81pP3zJI<_J&gF zX7>8%Qcxp#!3TzhhcidEF!{1yY$zu>%&VGWNP`CF#T7|Yo7>pNU| zRdIQ76<3Xe`snf_=H;!)qHYu%Mib*-1!|F9Ild;9)`7ooj=Ml z;qVCqWX!sohR$ck3Nar6ohGjjLVo$PnYP1gy7U=gKHSa6SO7;&h}%SU$@93LI!gXwN4Au}LoOVf;j zh*G&!erKRuuc_fHpOJQLvzKTfllSQJXg_df#w!bAu*^kdP3_@}#Au1%H5w2ndPg<|goZG%O2%oZzwm+9e>O z3(o5OFM$*ah5n#;6pn-P@fHktU~C5W%};DWLj>f`e#1BuT1Ia_QUOSKSy?O%)U+)s zT3R%@jkUF!VYDa^ahsNwmYf{g83M8q-~C4eUT&8DAc*rb5=CQ!R}A|oz5S9np-g<5@tbcS2+q16h`8irWT>Bm{M0qTKwn=6yZ^GP zIVL+nP0rzI%ZJq;DCp?n_#%Jaw#KuqMFup{)6q#vN`4U78qBfB{KHXOAPr%AzCw~N zEZYC$$CJC*gakBe89BKi4IE@UekN*&5Z~9?AX{HG9UTfJI3hj$-Q7!X<*t?pfdk4=gGr9EBaU&!%?_l=CYAJ)pf^ zbox=IrZIm2&l_}5jslAWP;mkrzjm4oG{XQ#y_c@I&fk39VV^$x)rLCZAVCd^B`{dy zYAzn6U2!MalD2Ro?;c*kmm^+la!T?PH$&)=wmO(4b@AL|(X zPM!#V9R87C47aE~f|*6|uJ^yxeSg2ikrdM2;CT7t_dtI? zlkKZ3#p2M$#~s7MJ#4zB>@S;G@^W(tiHQ6MiJzqlH$QnW7<_yTu&>ujtR3IR-DswZGSLK()48X3jxpK8cg>eUd`aw_pN?=(ZN(Rbo>j z#SY>M|9%Tmzv#EJ)>J$)L==GeV+8+}Lj-czT3PXZA@=tm$3~-Ayz_a-!to2A8DBP$ z(Mg;@phi8qQdjSB`$T-r*_|hm%-0A)RPDS~-{CeAzZ+eQ&i!1e^>Vqh>gnUF3gPB9 zkRoYQy?gGi;(* zpkM>|><_u%PG4UifSKNM?MxPvzIr8PSOnh8$jAs>mB0?PwzYxJpuorf5d=Iolw@RD z09S!20wQ|B7z$o2FE0#K@HBAL6mMT<^RNFW z8X6p&VVa)+UO2kN_JrsTETH}2;5{+0us{_!A9Q=eNw~p&f)s{kKEeOCfx(qTelxTwgQT#E+ zWME);&LMsFMm&b*QzRgafZM-sV^T8twd^11P#r9 z#5Hga+x+=iY(=0^^54g)AEkG`!&IVpGyen0b>u{~RCCWfpW!uCfQB;g`UHX9%HUB) z74FcJ1V0&60P)BNM^94nnP@PpSQM{;x{?z9-n(tSZEnQus_Lk41!iAh&~<#e)#E3> zI)l^o9+`Q!?6NpM7eZHPTRFDIKycIyH#9VUuNw*b?`y#Fhd>Z=0d^R$KZa?N=tmWQ zy(IDo(EW(^%etaD4_zLWIm*QE?>nH$h?`+Fvs6HLX1YbzC~( z(*FXf`S=o9{XD;ZEhm-f^2|Y{zK+3pG1H-QyxH`O;w8trxg`JN*kG--Pf?X<0L%E& zz*8d{2ZdUyQYy4>j zLDLNES$ma|XDd$%0Gir`kNn^rA~nT?Z@#yzt%#2(^fYUYw{2Ox4ohU@X~#zNU#t{A z9+k&Ohd91qjTo!X3c%V9Sz8z<+t=$h`9wi&`lV`7``-hebS&tK&Z8R^grQuL7_P$P zwH!2t0sk63VjeIvk7&Tp3T&w94=_-JIi(#q2mX1=0Dl~; zJmH_v5zJ1(nF8i&AO33_7+|KOdzQ<<#WfCy!^?L6mYR~VygXWF_k2mLc;S2nZ1>W# z8vzg{U96IIBg81cgz*amFVBkv#Jq5_c!Vw$g;LaJCqbZ!GmM3ihGrSP@2`mCO2qiy zs^~Rih>GnrS<5o&l2xgi-7;Yh<&yx0i`5zwmZlCEF+P_5uscX225FU;kE{(sLcAi0 zo`NvHyMP*y{S5L6_utj^`F6@C4$J7|gEVG-psj2m^KE#Ib3i73yTb8brIg>>xZn0^xiI{K1fwSP2V@j}*nfP#?;=pwiDS!;&JxoTRf+lvV0J*( zJ*#R)o)$~jPs%wXE-ntjmng!*MrOo^OoHi;yN6IB|CWGdRupAehZz^hycmAYk)cvJ z@GmCWC7SUEnk2?E#=45fkEO^q4JBPr`n>;!unK0paSfkF5#xC6w-rkKw?Wk_m8wu85|(HJNA2=w(lhs znmiK?*;Q(t9icRB=@T5ujSw2Jh(o)C0(mxaco;}Yra{Q@$g@tY-nXoHq%fmbdT&Bh zJT0YA{ir}DXRjI8caASPqgFhIvfN41eB}Xl_%boCark6Q>4^aBT~pWWwgoa$C9GmI?Be{3VD=D2@F}O~&735uUx?!$Hc|Zl!`eGW*BN(fzbm$l zCTVQDv5hur+}O4o+qTWdP8u~vW81d#-hK8yW1PLeydTcFGsYS#W36=?^MB1buU`e! zn851*2u};B1e$1bYhqGO%IgHt_Vo1K2dKC`>q7r61G z?!v;t0-Evl?QLO44iHBccImHB1Hm^P9fG>_(wPgu(gvUsOiVQZq=vo`@Lzs=djlF+ zfJ7>Qp3C-Iiev#u=5!K0A2?Qh;h5?GeAerM}LQcno8-__j`gsdu+%D^Iv8Z-8`Wei@3if zF=71OLj~(SY)?3w*^fmQ#6^Q1HicOiPae2IZ-}VX>9y38U>2^(Ylj^SMGqYmR|8vD zq6eq-3e{9A_?q|QqaJ<rq~10j&U_E+4xYe~)VnZ? zH(u=fjBYis4!eEjs7Z%}xMA#8P|CQzWvB!>0!F6H7G`+7q?W-y`zX~*ZTj_=BPdsu zAfj82uKAWrmI^z@pGxk-C1kLZ1PfHDpPbyHZNa48dsD8_Cz@5r8}`nyq$Fkg0ig`u znm+q;w2-A4rWw3pi0dCyx}0UN=u0Xzf&ER^Mj^#`;{Z0KFz}1b#jD2nn(x4^4IsKZ z_coL79em0sI7Kf%xSE#80FGNUz+e>hn;)2O)!@PL18D%{1t_0D4g|=A z*j-|$XbKkyK{-ig8RW_NnPGSUr!62A_TV*B{`gt?wG0^e4+d=uU^3c!@T)6LCINCOS|AO-bn#azSponIaj0RWr> zjhoM~ehE;ErN~A2iRt&Q`10}H(5^s1B3l3#S}0WPAKMl)Ulasl%J)EvLgR&y2C5Zc zTWOMHViWH%sL=timPBIjbH==z8DR#>D>GlWUYZ=B+yO%iE6xnSkz~09m1NML>ggh1 z^7vEvzjfOBwy04tM+zD3%7KrxE&@C=D**Wz9_kkS)X~+I3NCKgNX0>=Vh(7Sn+^u; z!e4zxg)D>?y%MI!4rszfcsvJ&_0wj6^0*l2#5)pO(1SRPr7T377+)`Z*lfn~PdKCqhKNz!9;3VebKS zL0e$6NKm9f-yhSZ9Dd ziz$vH*xlq)tbsfhY47ERI zBPF6Z_APH5EI%@0oT|7-E%*JCImSEiU@hGz*e>hIyl0`US5KA9l~nnnNE+wn?*5aq za3NOWbp&8M&wx=}BGXg0gYh`Ix`qI_qbXPo#3+dXxX`AEUU{zzf3`!owLpqMx65&X zt+5n5AQ(rf4M#;x!GlR{X+ZH*K!@55liy?t4r?}>*z?41*pl8y_$sEIEK_9Bn9g3! z8kT>RujjQnNtXELuK?&+OTewJt5-7Pk~v9+qU$GwiG8ZLNt(zwOTsKssdlVostZ%-4)wG7Gmp~+O0Dl3^f=mwubOgr+|vCQolB6hRP`swrEP%h*2wKo4Qr_11QOir zFyLD>752-^%>|t((1+EwDsq0RsZgO+8MFT^<8H)^jSpokpkD%)%`T_~VH*bpGe@1% zZ!8+F8GJ+)?|&|({qwL-St85V?J`yYHAe%=T=a;PdoQ*8iJ>PnHutZN$|gItVoaX* zHfz+U6|Yn=H2WdyM;@(Lc`P}F!yrn9cy%c#-CqeBooCDjxmk^z!Xh@ckbc)7d~ zbm))#pq?JSX@yTFl=wL82>b>}e#vnRLWz0GqTo+$i1R(NAhbV9{`Cz92s9M(pO5kf zQ1p5~|MYUtokJKD`HEyI>c~k5%UW<4ZGywfq-1@_RE)};HL+p1Nb=?oH{d)uBO+ zwo!m>&7u1*^+LbLE>_PVW^(q~0ot}d4CDK?oOVf5;Oub@B*Wk&eZ2#^yz77t>auXt1k(3vw#!^Z~nUc{BZSq%J>S<5s&H#xY#QGErT zen|TkbsF?0q-cC3Q-l@+I9L`@kqjFS*Kvhq@a-(*o?=3~eV1ogRc2Li9MvYzj+?lLm)Ba%~bmw;aUdJDh^8X6jaw}e~@ zfWir&M*z)MPOe{i3y>UDe)inh+uH*bZrqlcfcTpEpD8ghP$FB$SDZot>NF4W?+jwCBG^3~jsC-f26BidwH?doQ+76_Z#SwB{fCYAY zD-nRAzhwYx0!*=Bweb>2>4246K^L&az=XIijs}!GAbJ1^PO!v012hs75fN~EjKiYh zVt>k6Pher>sGUHzf*#0G0pn;E7PQA5@ofbwEBeM{VAsUP`WapTIy;PYFSvk!8R5m? zz<}}@?AH(=(_=W>gMIt?yT}f8hTnmqq2X29A1FBCg&ufxalhm%>|rAV15z`8lb`5% z`IoqQ_ahJSfMl5UpD8spv{}h9>_ZNaKeNT0$ugfM?_z-6ae8_R9JeliP{rb+#w@De zARuDL7Ur>vYHJgsLMR#<7$}{!I)SGyCfTF3C7Iv&Sp6PNkE(r}!^O6F?{nl!zkA`36(Y6vJd zGs=dj5hvS)a&FY7&4^NDNBP$Xg9Q_Cj> zCK~08BH`LT*miYwz00079TtFgj*K!(DPd8rYl@6bhc;y;h7CTaK?Xn7QW7Gq0;j`DUyoaWOG6(y11meOIdr{*A5+2eMuiBG2^-tTg`;ImdOktZk7_L-4xhlBqE* zF;OM2M23tatcdYX7ntH$p?)kkFflVv0Ui+S?Cc~YB)}^8L%b!S zqf`$xx0o>iC_&(&92yD{l=Gk~MBgMM#KaWizR{ym{2}n^k~cW!;-?@nh5>xsXi)s# z2NEy_2GG=7KY>9mGnz5Qr4S$*Ps4jZy}SgtKK7LGDV*PY?;DDmjJT$!^g2{O&idf@ zhDAg~goh_(#6SYJ_{!V;sA%EHvnvx45;73b)q{e7f)Q{(N_v-0}~c<_^lL_&eMRa7y3$n*iM00}g4LV;KOKt2p~l zf-$?2XV=4|VgyACD+MQ#Fo1HK=*~_c{Xn45AV(n-6xveAszO^a-JXrK;b-w?j7)XLpR|FQ*o|OKc z|MzRaT6;vvdJ5@5GQd5n&bn>c60l$CGUnabut!^ARWxZ9?l7XO=5?0;UhaUuc*iEjIZ=nIdK7zKQBFCa z>C|=BQ(dI%f=)Vs+K7B5Tl=h~v#zVkLeS>bms2dgQ85+mYg9AhTk7E?)(LO=^O`}$ zq^3NVoDb=^P9$4x{)-;&W7MnqQiXbom%zAA%O$PLk?KAgj%yLCr)rv?>OMisVgr z#S886&EJ{8rSsK_`d?o@XhHa|Z}|P!2mU*Z|NZX2e;?icKYsDQ{w3i){~yco+x(yN z`(OWp{y)zC|FX3IJ^TOL(*F0_|6gYR|MSNDXJ7SnLp6O=K{U;%K>e??Ng_Bfl} zC}We=+3!~?Or{grERI*@DDyU}bvHx&p03_EbImX)-gis;*2LCNc6}v4zCyrTP+*x> z=|m60(&09WZH22cmEEU5(0+$aqXW z4uspGnoMQ&zAvuQTMJiYYJ}DPDA8|LzsmTQ8}t9167L&_6oM@=J{U$L-N12IJT?qL^-b?v!6LlOaz~9cDE)4-?neY zi7Pc*owgIV3@JO>-6mG?*bc@u`Fz*&gGNo5G_Hr|Ar3AOz~+3xGK(gCR$HvrQ_n9L zwI0^0A-(`Dt{c^p-H#q8zsnL}qB8kEMu|TTp3lB4L}swGY^+j@3Ov~yoO?^&d%xUq z>G`x7^)@gX9xy#^qX=u3bE1BSn`C@*Fxu!PM*i^G`eBei@i{5^&FD{fr^E5#R^N;7 z>)r1p$;s=8vl(9-C3&bIxER|UZtvT%x`czte@X1!Ei#}Mm+$4$UafB6wY)0v*uZwJ z&F(x!2f&tG4H2j@X>s`O`D4kdSFhEc*Vnibz8=j+NlGtK6#E9J^DXy)2Y$xv{{V@&jI{X$B!DxYTby4aeA-2d+v-b63*x2rN5>=FHb;k{j0_3 z5ZwZ!UX#N#fI7sfde>ir(GvLBUJ39-`S93&jT(ZJ{@&_;3HP7tIQj*l_K>Zh=C#TF zDN{LM!>8ceO0{h#kIBew5W+&`O2b_{QZOz;U z90wa(c6al?23%dJCloCmQMB?>8br>8mJ=wKm>AjBCbJA84nIk^UWtr#(n@u=JI?uc z*&^X{SnbBz-$ZA14UiiPVwHT-{bFmh0Tl9fuz4+aDEf2}s6S4o-1Ec;yx85Rx;`VF zax`pQg6#|<;t6;y#tM6TL~1-a7a-J2sx4fYr zKCvEV!6leXXtsFlr6U25rq!0MPUDNo46d!L_keYL&fJR?(PGBu&GwuL)0GNM-a#F~ z)`xZmvW?R@7#`{$+WVd9%lUi*Ot)9FUH|1d|1*Q`$8guq!A?X} zPahvZ@_?;OhCr#n{3Tlyn~`v(z=f=eN05@xt^~4u!HQ+>1 z>;8T9f%D;Pk>=0e{T-&Sw0|R*TjB>WOu#O);E-0{H3~oO{$g= zwY#2AOb2{3!Y=sV`o=BSS7u8*+ta^h$XKdBL0P`yyIgQ=7s$(YYw!s(Ty}kB9vl$x z)Wp>SK)c!UT3xzK9Zix;w%_X%YbZ?%7Xg;Unx*x#vwM}vov*~`(2%QFt=D_A9&tyO zZvNGESn0PK52+TpL6+ipbIfd+MiGjN?YoY`l9S>XLVmm1)w>)*ZXX6p2G#zj1+zKd z<5wh4AHWIZJ*&MW#`~AabLhD>xK|PdOkN=*mW?D`~|4Y&4!I zV0)idum83Hqqr6!oAhUu^rZQi%j$X1)~CbaebQ3Bn&`vjW$fxr6Y>$)A$wqh@8vF8 zH38@%;dObJgsH(D<@`rrfbkEfs4@FmNB7h{gbCyG-E5L&3IJgPO7SH>xLsfN%P<7T+)K0y zOJp`Zi*jW>iQY)QP-KP8fyuXZP9Ka9R%J}bOePRh?G^z^5H#x*m*c;k?$#f^Qw=vu z!)um;>(}qmH`3xwp}g{aCv$Kyu$M8HUq{xw`28W)cHz0wGF9=1x*B{}JlUvx-8LUQ zrRQq_i(vwBsNgx+igo?|Qu~_)dOVI?!wkytjLvD_`Qyp;qlM0o6QESdT(i?eqa~-A z>}(q6go|FY@%r#-2#To&-f+U}V`*@1rRluok)EHl!y}*=seHj46HU!}YP0UIdUv(?&mDPL-$aQ@HyZuagxj5h~jL8N*1olm5!GswJn*$CX^<&jpkB@d_$m z0iPY8uL6eQ`vASSN}b`)hSss(!T8pIl88rdz#b zFyz|^W~OAqzHNi${RxZ9oXuxnO9Nf)7#7C11@{Dc5@hk|x5TTK_9ydb2+)&zlSd@ z_D5I4=1|379fNpa=6!$K+~+sk_7}FpDWY$q7hvqv|GI@@YSj4w9_gvysQF_n52)z> zas9!1wNuFhyy)`)5%53$~ zkS?hwyV7%BY}VPI`BNK1SJ&HYd*e2txhdyI-gE8T5H^q#IZBb@RX1! zs#uJ1om9HSEp0Wd&=M9Dk?g-t3o@>TO~iY`JU+Yqkzu|0g@D!TeB6At-fbFUVZ-$O zk@J(MtK|lzN~SFhi>23FNBII;T75n7D(~gZ)oAnfQER>@;04a@ekN1-myMdbFkQol zW}LQmq@fqd6B++jZJ~`x>rYQH#5&%3r+S108kkFQV|bx}1#uG3`$7(K*7Kg(yPm-& z0X8A(T&-GZh(F8dS_lf0jxTUDxk-OXlptGMz_gd^^m#BmJ6o-B|7PRjxi|l6U?2Bq zl4?<~XTjXKZhAWGYUy_%!@rTqrSBhmrV(n!8N5^0fUo6=D;&tSTt#EKiryZt2mC{f z0+qWI&Jp+C&(Zh-=DW2&3aAvnUvH`Zv+q0FZuXchGGETV-t8H>kSFGMQTh-Fpi(`U1}DLrI&LdRqXc+Lku z2xxbjzZEA{Z0I!_O}v)X500fbZU=};R!f?yq;Jt;NEgX{#u^6N?i>?GA`L2}_As`! z{*uv4eV*2GD!OWRu}+_BRIZq?{^D}MR(KHmP8N(z$mMc<2=o|Drgj?K98fXxNsY0* zei|Qx8jhJb{V+Lcd!USRyUF@-(XmwFnBpV4ehO4KZ>+z0Je)7RRW*ko67c_copILc zT7TNfdMqr=?7rImWKo#@-a^3ZSsLKvK z+(6N%@rOhWmj~wsui17>Sq7(#Mx)a-07}PZ(!D>=9CqBu60n~4pIdqO)b5jYfKKo? zN1GQIns;@2G+V70&fGo$tD)O!v*t;+U!z-Rw0|13V_LoHxceRva(86fz0qXwp19t* z?p9zJA`Ai3$>FhE>q;q?$?0?5pN61T{c(MgQ^T(~Mt9MdLGP=}-S%=*!|7eCzgWuk z#hIvXbBFl4@`KpZ^^@8_(pCZT?qI>{52pukkXpu%)3t4S?Pj zE^2=#*ZQTkn->TzzJt}9?1zW-f)mG_13umRvC}k;`UNjj;6|arK!$-B%ye2J6Ix#` z(4hd201F!)t*Eq99|($@755 z=3F76xJAzSd+pQ)my_}8b3@fr2vG-v?a{MzO4WpG+6k%Ymv*_FomO6U0X_jrej4+? z$<}oh>Q%@(4ZQSj1Hp#Pbiw(=cWX}t_F(n=CT(r*V~&m)t!DGDOFw%ZlP7gqJl9{1 z>GJ1o`Q2XdPKXcjgYzSMQxwnj+MV7Pr@zJMb<+80U2iWXh`LVjpBFm9k>kaqA6j3y zxt+|MrHs!}d{T9FF(&d=+K|NgyhGlI72ErsU(aQ`3aCu`OA!ke79O53zCKW*biAp! z*y;5b_TOXTJQoLFJMo4Ax2kff1nJfNcOrb*&>;vyln8@M!Lp1mBRL!0Hc0 zCFrGQm6o;z91lui8vdxTWwXLRV@nH*i>k^X#4tmSs3@zfSuH9D+z^xz!IaWUafye9 zT%6Ss)e_ge-iyehse7N@j}w?8pRT6o zWM;Psc<;1T%0FrSy5>9^5lqa{+NrSW7xV~VIVjNBnB=lRpIG*FddN}LiK=MI9N!& zPi|UlH9R)D+G^?8JOA7I%QdIXQoH>@Tw}zV*Q$CUk-+n@`1iRNt_!*fi;Rqu6AOHc z>{V`8Qm&;*S9iPn&SN!DC|}^lH=WyEm#fZtPn1&`S$T!YwI&L#8hrq=)A5^O#RYr! z0Q;23>&5vgMZOnI!B*DM_}f*$iEZ}Aa=qg>?XQ|1*U#gv?(QqUnrz3Hy7|dWCGY3j zV~AG;SX_T~*4r8l7OySXcG{j@5SG$;>#4k+UY%)~+UT~l*lG>7Z3@+tA)nuX=i91z z{muPz;h_`TwNAxO?P7gCY`8#8x=qF&C3!*<7K_G*B1?syG!P_5v^PBr5fsGZiQq!W zXaBmsGX&E_-11%f?>tkX>-{}@QU{aIaiNK^sr5!1jj8DmVPJ#!Ll6)U zTrxYnnoIX%d^xPKVo+>CGx;4S5Sy1G)L{n6P0sjTj*sWQIDgWXruYO=fF{xA;W4wA z4M6P{Vu+U78Q6ZDmDd)1J1c2pydB|jYHoN7p+oPg?J9m=ix^s%(57DO`fMxeVqvqs zoY)Wa_S!7@ILW?GyuBb>$;(Q|gvF$v>~D2aJ3cI}pyVW}Cnt7ScznG*?F%W7E?+Ni zi>JeRIH0V&PTStDqksDImi+OZ3%;S`T1`{rkCSUnP{jUH3>PumpjGdyc&parH#2Tg z1O$F-hoiss$^rt})lJX^`8p99gM@q=@AhTqgE&viB&Lq z@4Iun^u+)$7Uo)!4krL#8_{@fv(Fe?+HpRL2<_ z88{kk+cK!FC`HkGw<#zftJ{-}jTP7-@M zZQ4KI&yW8VgJTmKNE$}b+ehj*U;^RSrw{4HsvxHlSjt#j$oJ|l@=f`h&UZOcL^^O( zKC}Q-P}K0zS+#AImBsrd4M3q9v!-N-nCP~9nTXPQIM?B6Ggb64x^%!ma1SG{IXcu~ z5>QEL;B-s_N%lKCH#s4?z={<`I^R|fEiIPrY{C)vlN@rvpBKhK2S1z8{+iK-E~;sd zn;AWj9W}$nqaBTJ7vx)Sv|fu3Vq3)ts#$3R;2B)R_$MFRJ4!}6e>W357b>1DA}$D5 z0ky4s&Wu4-m7{9fa4-WO&(e}Q8uvv1M`003z(*njc@}nwo|h6U^VI9s^HpGxO~RlV z@D)7VG~6^T`P!MkN(4N=XJ)2^bib?ZqPP-`h0!HYlcPVD#>0$Zzk)7=XXQl~#txh_%<( zvy2kJK}5j!S$O))Feq(n{qG%nQj+TJAbtk!Az9VM#-5RcWYvmqQ9O*1#A7j`&1Nlu z#k$Ti5y9b)3L3@|j^9d?i_4bxk>&{|Qnk;z=dy~?y6G-?xOI&Yi;2E~wPa&O3U5^X zOk6^&%FL8X9rOIRI5en^uH^CuRgNqnuSD6y;*~XeVef$xoidhs{=pa}^&~Ys7ERyC zzlHW{lw^^TY2UTd52bwPe&V4`XK~v)ujjd7FKejR8CHFag$;Tv)Bd8|LAtXx0SKu} z&aA~J&bJ~5W#6!~st36lWcWO43M1xcrl;&b_8Wo06W#T>5tx zU%lvz74(nO`W#0_1!+%JhxNWut_qn80q#b3|7>k_Jz4K>C@JGOAR@!snl3`sY0lyH z%i5;)hozlsSH*Jy508W1QOoI@@ygpmiB@{#(YBjB^V;U>&rA$fTbOhO$`ZTvNR)89B}r|KH<^LXXFo~%F(R)~c*N50|H=;YUu*;h7)pce3v6pEU2) z5N~w2pY8X(#Ejst3$!G)%=S&oZ1m60|2Am&1$)-FhA=Ig#cwjkf17`wQB?l@RKTS* zc|r(gU35iqT(%wqm_^mo4+@%HBG z4k0`;O5=!YU|mQx4M;C8t%?tX5o9cmh3euYrC}0dH7%QVb%y^!tf{W}RUxS+Gr7LB zHso9MVW6kp{KSUsrdZc7JB7R78!$-s1tQsFFVhRa2D+DRd10oUBQil&&p9FscPaGV8A0|hyLAjKMRSTr2ttk~FES@A*QxVI|6-|yG z{Pn037)nYF7a`C6|PWsD)awWCz z%BnKra`6lzl=>~eT`$M)W?yfV9U=vUFrTCvv2cHJ2R z@p@;urP&D;HLaHBat!A*W(f;%_T;1n7Psj;J5!2#JvLM@h0UVx<$lu81$BcUleCWG zi!|F1-k*v(_W+%!Dh7Zp)}RaajavUs8P|)5nC$UhTO#o*mxH~d1M3_rn(^|6vvb>%bF@&im<+;L-_z5w-%&&u;7>Xt%^yX!Qj6oo}}bm;z=Cn20+)-Ck6^ z5wzqLw6(v=3ui})iuJ2VlpaZWzr4j$0;WH=X`F*f$rJk!AQj2w>aghhs|Hv0*mnoK zsrRkl^YWf3MAT=4;9_$#UbocZ+xo78G2};^TWp@atW`{0J$tA76ZTHOdYk548y32r zF1s34{d38`7|d$Wv5^heOx$XE6tf*n*5h+&PAQhvP!}ON-PNXQ@AnAVN(u($m$7&# zTg~tPjd4&9VZ8jF{EKGYJ74qTz=kAjVQxF%&nFSdu3w zstTH4Z*B2iI2y7hX1bIrcfqhaGnHe(-8*C+1%nDqZc;H!aC81XM7x2%kRDpo2h98oIxDHQ(7vzQl0+MxNQ|w#sK)esp5yW|rEU zqTxsUyl=`s@I44E&r+?3(-~n_;=6*&FEz~Gxy~vZ7$YEbVZpn?h*a&))|@nQka?V$ zD%)Ag%$`?k3ck`X^|Ul+HS_gk;V^U@$qrd1jxjD{nHW7V9~sW)hgh?IQ{fC6H)Ox( z#Kux*cl29Q`FQO3ee%-8m~F!`?BQQk;3)NVeUSY_*1cDN)yNtNONTId z(vrqwe*UuS%61;X%MWXs1tDC1z0L9A-Mih@$o9|pO4hcZJ9(Pg-1?0CfV7rp)$npk zdM0KkCkOu*F2Us$F?@A_sZ~|c1^gYXgmys=_r7Y;mug);pQpuWiik4_IvJmv7BJAj zL48WF1hK~~oL{=6h_J59Gvrka@!hR5Dqpl%&$XQ&ISD)%3Wy#gcmnF*-DGwmB0yp0 zwkO^E#_dNhrX)r}%1BD)KZ5v|I%<;~6%ma@gAguchZ#*JJyc&Bk~eEXvY>J5CAb=E zu0aK>zaJLdgg9zsGoLk{9F22kMfv_(bvR=ItIx&nB#(W*$>{-+)QUctTml^SXMYhw zD!YZ&2T2y|7@|l|(F13f=fm?=!HVkzpXc4}(_i&T-8I2Z20GHIFO;nAf6s4p2y-iq znU_aQ_J3cJdD^ae+)y+8@%|0V;Z`0@0{e^<@CD>&c81qrJUShi$h`60B^>=UJAH<0 zQZF%Co$J=2$f<#HaXBrf4!^9Z=e)|t?OESP!mBjqWel&rgRht&>W_f;hmPorA~Chm z1J|5SDZwr?2s%V2!a#{p!7m@z&!9FnCo70%{7suQ78^rfTpTSi3XG2uS~yOS*WNb> z0R%>ciSfDqC{kC37#l5NhS1#7l5KEN?0AR(nev&VP$0bs>d+3%h)woLi~^$Wuano#@TTe-oQl28ZrYo} zfgP9!;#RM#ndyc@W0%2e2fem_Rz1}e9gnB-$~G-caZMe?>h_eG?`u&QDSz>Qup0ly zg^0SS7Pn)K&*!wk;4u0bec!@zKOccjX)UD~cGdWc?X?^$VL?}QZAtM5x*aG4HI$q+ zM1)w(oL*ogZie`Pn~suVQTpj-wrzrO6uTzf*3`Di%v?k6I9TV)z0IToehKZ>+PkHd z*~ys%3(%(^%%TB4BEh5K2Lja!uHlJDXjyyfQDH=2#DYO5kzhRI$w}z7;Vxi#RLSJHedOhb$njw%*N zP6&r}$pahLPZbX(r*={BOR$@5c6CAe#01tJTp2tX$&HV+Cr>Z_t@eh6J~vDtOTF5F|VprbQWZXl#WW{i(7#RIRL4k7hZk-W7Wbl=E~wz7Qj`N)8y zBnmbMBHKGjcXeX#DHe>F7(9v@;%5*dd{Ju*MFFQloUeWl{KG}@0^!yVOAdqhY<931 zhq6~6O&oDQct|0sL@)>y&V=^|+92XS8@;2y2n*|cU2}*a<_7j0<{z0q-w(gO$YIbh8a&XCRXLY%$zEP~;h5Y)<;j0DovBThg^hEZ#Sg{cyE4m7NQKnOtdW|Kjl^1HErpS^0^IXN6lMG7-<~ z<#;e}oW=1|R!Q6V_>y;brFSYeHF}sBWh~lfXxJdXDDd4HZOK?=#t^zqkihRD@O)I* z%MFgXH$-p{35geDOyG~3Krw+7GBJwUU-04iGTXn(`zA;wlNXXPRI$+pLLHS5v48x9 z%ZG&yILV!QZo}sl$T62Jl{K#zMJ>9#{aM{BfUQVKMp4jnX6fa&uW=dfj?DSjlmR|8 zQpfl3b&sGq+qLfJJvBn}ldKo^1a3je(_32l@|ew;mBpE9tuokV#P+Zec+O{^|`rLa*T=4kJ$kL9s z;P}v6yCjV7>C}nn5C$3o0kSD>kkcJmX$uGW^9OzM^_-rKr4@!od`qBQg zAg5Xp7Iw213^K zvH4`KHHf!{FbdQhhLl*q`sZ$NwfKg2mEYIziw~LRv^d_(W(TY^6_O8BX&&;7E^A=L zFn^(|kd@KJ^e(lsFc>z^XrD;s>h&0t;xUn*eoAHTHbyHu&{I(g=9k=t0+DPWvV|hP z*|zXSi;JOw6NeZ)Z3+?+0L^6JO3IL<26%S%74FH8!oq%%{6p!IRx zvbkYKQGcP$pn##n*a?X#tSAlr={HMkE1#VVp~lGv!PNRe+JWrqL;?f0>{=n+D}{uW zwWSFHo}R&B6j3Q6;-!2w3#o}feo#Vw?=UahhLj>8A`rCy5Crx}K>;M9A~jiFsW7g< z?2o#9gM3;edptxvzh3(mD?&I$i8>L)pL0yP$eUfnzY-pbM%kXv8dvn%_{6|^wy!ps zY_Xf$^6IN$1f>#swu87ag@Xtase(6oAX!M&AP2(V8#v=)Qxc3z4W+5$NH=9`-RTLj zV?M(!2|4(2N);ffzvY5L!2MvXFmpi^pUFQbkcn<${8`+pmI@?niXGj_x2lYVR08Wk zN&1O;8RWHlF%Jn&i2#~fda3KxWuBV(t~DcL4FQV1jWjkkV#z@fQ#g3aPig$L#)l}Z z?Ht&a$nulsxh&RwhB5@py_AUR^j zcrO~WHlw;9Ec3Pj>-M&wZnzYNaiY7?cR2b@@IW$s1Q4x01iJKBKYh5=t!Rgzs4+u3 zm)wLfb|4vaba!f;m|R490;c{QI3xUn8w?t^g0P$V2Vy?wSG(UMdl6O)xAKGOmNBf& z9BgywSWVt;UKgi7F%I;c?dAAHuA{Zv-M8G5Kene?aV@;vb+p)ik||Iq4P24i)0oqL zcUTODXMyM&2Aig7)l$qBblsfl^8Vsdr8vq+y_%p`%kS$g;HV@hI9*zVu+Nm8;{3XIiNy#hjEZ>P{W(dwiAWa0KVaePi~H&6Ri7k+YoSp;qn%@u zQo`}Mr9~xu*HcHZG|AD595b65`VewQtMlFS-3n873iNdH1sMu>z=0EqFH*wG|@&a&WTPK~*l z$%N$jIj%YuVp9tqn}%rCjD@SM^#T5j9Ww0kyW7-m&WE0pWu~=WWyG+MuVuK1(I}}R zB+wvYVKh!<*hM44m>WSKyfP379fXLv2_gYQgaM=e-KX@?9V74))C1!O$qa&hf(;o5 zEKw*vUz5k>G!2I9U*;PjlJ;DIp`cwaY6SL6J`zHrUcw4r`o1{oM;L%4{_N~GkSWqMs`LUA*$e{kAht5#k)CYs>+ks`_W)biocx$+XgvA}% z^6J@#vm^A|s%z=H1N%)vjSL0~_|)d`Ms>?|zLvIi!C~F|3I#lupBS{zu;c7b)u0ke z%Bza2Dd#V5x9|V#35*sPiirMBc@aP3f5N=%Z{V0K6!RQ8$Fy2$nzz1}TbbS|9!n+2 zP<}lB%b~tEa8_60f3N2?3fA+-CO#<0;-p0)|-?tm$W*Z1T-K$2-gx6}Fg zx{-^*S)QF$_^VjB9LZMEZqi;+k<=;5#d$Wr)9&%Wi8>R}itpBIeF~Cj3Znr!={EQ0 z@c6V+p};-}H&U=Y_&||7KMCUds$mVx82BT4KPtF7NInERJ1>EtXrL!1j%3GKrBJ26 z`|K(38*@VrR=4xyR)i~)9$zX@SYIbVXZp~~4^zYMt9sj2>63eW7Q~Myj8MF!Seqc0 z)~Fg)Wu52)k0Xl-|0D(lm6=Japse;TxD3ZC1FiNAN1W<>Jrk?dC>~D%q@*%7ViTSf zm6exlre%J0f4kc;uJz^d(g^B5*8+}$>v)2tq$@cE<&ZJvYKPW>%v0WHZJE&#`(i~U zjovL;oS5@Sqztw}C5$~M=9Tsgt+pk;@AS!ZF-2@1hwKV9n=8TcoXJ#1WL`Z(J7765 zwWWSRn_|j|(wI{4mxnRJ5XSIj0enQrTg-msq?r0(L|~cS=+Xk5&7|Nx82Ud^v9_fl z1Hbh2)Ia*?G|Fv(smX~Y4s9oZ`6J(vq77^<$$_c&48hwA5+ck5o78(1MC-V}o{tw5 zWH|b(xlOt>)#2tz?>oNGR7E*+sL+z;m+$SKvj26?|Cui(Ih=%4R>vY8MwRVN`0`an zI#X!yCJdJmz80508tG9CF?=eFTe*u{SnkyqGYJf&0crsua*{Tl`pvB?Y@7c+I3+I!KB z3}Z(Prax7abL=Z}d;V`i0g5`rspsDW0 z4X97XK!&W-ZD)FoE@Tn_)_zRod7`YVJs4tQ0cK3%%3kV@1NA3dOs8Y(jrE(iQD1B= z&2+Y}fhr$|eAtwAwdeiyy?XWRq|R2yyWau7f`2N0nxL&%=WKdFxAO~3Ixp>Xr~l%X zeGnNI{f#h_(!I^Sb^OL5jc@ozN6^A;>#)|nw&#WzDe9Gl17v<;Vq#=+vVW%B$EfAd z{1AQi))sG{;TEeR(`0PwDApQCUowh_LsL^%nW%T>$O#7homuLN%WHq z0v@|&O04|ejWVe)A_!TX8q?tqH;p|FKU!pD%b}vIrkeQVi2ZMNPpS|&WJbpMoiTa| z0!!a?O}iJ7t$-BcJ2^%eMe=J@>|iFUvdU8K-(x+0gwQ@7d=?B#CT}zMj!NZ)jy@$3 zTX;fZCJQNiOA{k^c>c1aisT1I0_(4D_rcGeyv`&QrLn)m^At7U8@OaO5u$<Bk*@?XE3G z_!&*w2|i$Q0Et|lv6OR0l<639o*WVX9K z+Tlhls@kBWX%b)WZwVQdw$5Ga<6T|klf0mcy1JUS5>_l^%TK^!Dv2qy^SMt(1X!2t~%{&G;{z{l8X#4jr+2m+X3*4d;` zFpw@Pb>zsvCOwSLTkLEEGz>h9)lZ6_RU}*iW9NXWQ!di$A0!83S5KXeuhD%yA^L+v zL|nqisgR2#VlgqfvyN?lAwheUi>eS{)Sw`Nl@MJ&ehgpoAh8c;{_bdy4<8#2m=6jN zqC#wfe#&_f6w0!#URkmk)i#yGc#D3PuSB4Y6h!M8`jJfCX~uUnR?F)I3adgs8g3qNbriv57GK>=iYF zcUoqdGrd%e8O!C#Gys*vtEQi zYj4Y(*%7}^|Cs#aB<3s=fiDn6f{Vp^JOOc zPsL%8MX9CPo<52f`t8l3TX}9wfOnT_3H`ph&Rza?Tznf>W;$A8lB%lHsk41gCUwGi zmj2==KR?oF!C;EekWDb(?w?@Lk=yiwU@90HwZQB{*IR?veA;pqjivF{3>HfSi7)7f zOPoK3_tUx5QRY}MdC17%@Gu%lUt?{?`@AwCK~!Gcp3<$N(riaYgeaM~ZZ9kZwfDd- zJt~8@4BF=bJyfHQpJrwXhU7I5FE6cO&G+Zqj(f~ycBN4Slth7D){r5kOHZ`3lT(BIg$A;DQ(EAD5@(7eKX3)7-qe|OLTMM9Yo(I z?WGs=%DTIJbjuG)sSjw6=z5$0t32h`<6k5yP=hBXipe2%Q}OG=Z+^^+v#J&+rtWVU zy_a5+bK36qPgk2_tgVAeIgy|WId&=J0wVx>;=_1p;;ngxK_|wgVgF`rDr0L)mrfuZ zCoJY2@p?vBzW*icP#lxeb6@SlJjMxO>LmK!A?MZ~{ z3k4G)c%7A%m$)iC#J=`8J>>4M^?dmhM^Zsc<4btUpgMccmqD>KXiy!UKIh0QA1C^g zUDFR52BZh?&xV%Kx4&(zng2KP>PxwN@8$ONwi6eCCCX7FkMvbPee#02+GeX>thCHg zoUBb|SJ&YSC(xC3eRf^?BlpdjL3&Y5N$c+N4trRJrMPX+(Av|J&ev}sbcC29d|7p2 zW(JX@|0q1^hlSts4?ayvZ9&aAIs?5WRXn^cuyRlknyOnXi8uB4Yw`z}N6@A$4>B?+ zbMQc4&ZHV*-%`n#?Xx+zlsyeIy9ucpsQ@>Fz~FbwJy?*;gx$0cduV}b1X1u77-+b^ z-}f!9yq^yY&Y)J3%h;JSLS9xuadsZJhl!X)NYc{vsA>x- zfH3Xmw%UAKySsSUnETjUSh(10A04eXwe?QLPsGv-!J&@5?eyBUuZ?7E^|z*^q^&Jg z7>Ct&?w7?KvmA?b@1okhon@H z1Qk`-Brc^7@t{~}iOHbsikS>9S0kyh)_B*z9xm^h((B=FQ>za*9sXw}6&443M*p7_ z?8C!)@6;2{<2!flt{@310SW1F3ZEWdK5^{8p1+~dpM~s$y;iR7-_Fp<;bhi}kDebv zI4wobntHdRRg4<|1as<1+0q;k$NXtq`;%y$VpI8 zJ3GPTgq**5eLFRyZgw_#m~R~w_=4}j&0TQxw!}Dqbk?G&xW-3DK~W-M?c!2w%DHHe zb}w2pH7<=_#uM&2ef7STnr#*t5;$J5OolYeeZD0j+PywLJ?nyz(Z7516nBn? zz$d>XIwGrmWs5h-h}H5te}S6SmMfNhQf_W_glI4n&A%G=%yQy%&4z%ypwTqxOK*1D z*+eEDf;yXiX>96A>(f!-Ifmzo)7s38)X`DaHpEwg5LDD{ReoRw2M)4U+w=nTa)C?K z#*KT{rp4tAB8&nH0pp@olMm?6snRGkU-R``yycwLfeZ!X_bG(YR+C1sI<%j_)8xR3 zcRcEHbbMe3OlJ=)J8trwKzxF^b^yThmu3Ezq0+#_-nIfDYtkZv0FX>1PPTIs24|lj zaTsHho-GU`nwn~PVO7hX`eWBOzXI#v$&RD0;b3Lp=Zi`BS-9_~Pbx5?{In6Gf@0gM zagi5h=jVS+pN95|g|EMVbUHJ_Hf9_@#3SClsj^pNWGt>tIsNd|ct85WJAS2m(N3fB zpj`hT_DK#cV`F9Zu|6v>JjCf40z!oR>o6kgu7rpRzF8DqZ&j67FG!F<+iS;Gj@Hm? z>^KjR(+Lp?zS5045L%Rt2cF6seJk4At1H{VQL*7+`hB1d;%@gzft7Ae59AeHgIkoJ zoqgLB@Ta|w`(-%v1;7=>^m9-X9_J&r68WAd+OKcZIV(oYS{k`k@^EomZcnj#CJ15zZ4;0>M|6$*Y#awWVG8qJin}0&;^(zp09H` z9$0|;&+}~|vCJdNz6kBvg`XWXH_}{f-UI1Gs7oi)0&1Tg#| zWX2sDS+##0tb?w=f=*I|3ip*``g*WgwK!opdU4i4UDXrX>Gn4$pdB5Q@*M%Az7vBlj2*k85P*Ac$;X@IO1=6WZ;t(0t|2||{ zy(z|$*k_#c%Ti#vaSjg;2M}TWNGt^Ac1BJVd=j6>rN+2D4vuPK_MeA~^ZT!tucreS z#`gwZ#)4H_$jmPK3ij?KL6y7Fu|}gyNinH-c+7kc1A6EvG3`wwVMmPQVbKIx+_(T} zNn@8FE1W<<%yPNg{~k^$*WOO39g0bp%Iw^KdPFG3u42I&{h0~T4neWc3tEE zakaJY=y>} z(nw9Y1FN7}Fosh?{B-?XUx>ncp!R;miJZ>kV0Y2)7Z1Bd+2o2pdwj1e&~jpUMd(x0yF~p@DkjSAOr>8o`u)m;Y`6dDBEi>_hBh#EFd> z?LFULT|7@aP9R6|SBYn>gV}YfJI^*j@DGpG_HDAh>;1*Zgm?(@wWC92ee$M))hP?8 zv)BFVn$%+E4h-a`t#h{Hx^S(a5=d%*3)q%L$;8PL)ilARkLyl9xxwWfFYQnbAP-ow z+ix2>4~05fX7H9B8zD1HW@;thIV{*Q&#yPzySOT!7T50T8=os&La4EefkEfl97-Z} z{(zTLV^+@73u^-An!9@vKM?bHO)>uA< zDv_X`^i;NDw{?F5jcj3TSgOV_WW1GPuhqu=i-BW1`*r{NSf$SrmEaf81f8x>WBUD% zCgcK(U#!Xtit#^BvJ@5P6&LJ-#YM$Mi*7hH9P$R9Cail%S5fH-FCFybYZVXqC^6JmA8Y6nT3u0Xe)Hv zL(V!*B9EaFoU0xNKPvcfAGw0nIQK=wg5Bw$x6bI*bApC6$2aq#xAltlZ;&`@;%h7$u90(UoWn~2n7vX8@P zqjgwfObQ+U~Qyz*ko0`hF^8auu6>;|kXxn7&wl(C+Z&8wt)B-vrAI&)3&AN2#?p95DT#KNEi7v~V%-Sihw-?bzpa zv?a;UPFrUjoN)+$1A&^g{~)Pzm@U6fo~}7w@Sd5P6qy#fK0j*n$xnWYG%@?dg5Ug_ z?c3G6DMW%;it`0x*J7=m_E&rR@PavF_BNTrPQjR68i$;g^e2$Ciu=%9?8-vGm|9aW zGl9ul26sdGYTMH#@V>J^Yd#`oN~k!T6Sae}z5pjOt5Nr8VPV~r znQ}9GQWrW41mC3P?10wNDzm{@K$~krMI^F)?G($*yyDys`bibsKXk6PH>=GQ7enaz zZ0hQ+jWQ1D`@i+*t)ELP5nab;?e%Kyh1p$c;9zBVZH{)Qb_!nG`b|XNP9-Yy%cLkCdN_J;Qqdi9edtorSL{?}qe@mc24wc%Fm369URU4Y@ zT{r9NPcM+U7{98LLx=oZa5y^L>3lCe(=%_*?s{YYg(#1doQj50024ueNs}ysf>;ZyKJ~KZ*x6-pIfzpQ|$a$i(F)Ae^tr;8D z^zyiL!-}OU87E{?*o=+6Uu3HL4KLpP^hzV^XEFtuG#Z>7LZbK{qiktykY5H;R@=Fh zk!jF`BDBPpjavbgcFSGNc;w+_&yVr+(>UFV;GMg;yISGHBC0`!=3>V`AvY;MhUdqp z2Tf1E20CA1BhS|%Qc#xsE*uP|GEH7-6zn@#YqEc^^6+clU5H0$yE|(7z3~)_)Anh> z@QmxaGS-_yOd^U@FiG=Rmt0HGr<6rrL(D6Ii_OVy#uUH7Bx9Y=HM8}_jTj_hVB5rn zgD)^()#R?l_DPz5NKr|Se^T@L@^t-hZ@t{Y8(VrETlXy-HPmIjoeqdRL%=~G29{@G ztnWJ7+jpm0L$MEaYakG46mjk>3}KG+Lz-sxetRm~yox@QTXJAA{OP{a!`xE9^s_D*dz0t^7ObFhyN?V-4t@)0^^*!E3 zG|Kj#$=MHaAni{+ME&KpH^N>bjr`=~Xt^;k7bDF>XFfbJDq2ao+Rh4IYNgeEqrG&| zQ2KeAw>&jB!M{XDR@6zdv7)6apE_ef?siYCm;x*9r4esTqf zG->H^am|FiYw{8qy?r5ouHgOcpmrv11CQClczUY*yhy3mH~g>haqWcURPN@2jVHNP zXigxI$#C~#%>-4*h9-BDrR914tbMZDQZlUdR97hGxMutBz2nEz?wKza8*E8fScMfo zRy%1`qob8?lzYvaT~GF(dRADC3#*#b24wS*d*cHn(_TV_N^czJQjb;Nt7L1&$#-qP_`QpJXR=44Ra(b5U4`BF8b zv8}`TK20i%%+xz9S@_2l%h{XLqSVX+PI9c-@qsDn5`s} z^{gtnA^M`!hx5hQCQ?#*E( zzY5Qvg&+bpuS>ZsuTJtG>=Xe)XO`wha@Lsp>+dH1f#nv7-H>SRWy$e@$x7rBSc%U;Dej0ka$`Vrkw$psPy@$RKfjcaz-9VvxKCO1M|1z$D z6_pZQ$5WvT^xq1+!)deo$6I(hcDGRrMbU{`SZ2M0fVi7@*Z7-jgTVkve}9=aE-D^6 z?ibt^4k98#9+$h6FrPNg2g?a53F%do6W)bkS%XG$q|0lUEHO3cajiBFH&2&8{F=i3 z{ZdV8CP&}C1>YErs<%>*5E3%eaJmYJFQ+6e`qhr+h*+$)csT0||81I%_U8^*G@ z;YU|MXR%neyI!2SOHRH512ZEc+Rn~F|E2G%B2)?+5-~c$UTdu5;9}I>y!iKTQ$)4S zr`j_=_ICQAU=wT`BJ|jrg>pDpM9puN9F+8qCs}1p-{i!GPJUr>XcUgThPO|0d8b75 zZ9fj$2b;|}{?Tdr<)1vB_$4G5``Ec0NGGo`S_@bMlTcYarg(3o7nvKilS)4r)v2fW zWq$h{clxRy`0)9BL^3=wR0aVVIWjynG$aTPHb}FLgPzKEW!+r^o~2wWR6;W3($St? zDR#hpBQ%qw#AF+@^$>5G+=4rc*zbpyrUgWaUs5^qET3nb>+ z9n78|2|l>S5!%h3&sG*jKB>VWv-tj|X=(d|UW=vOv4E30-Kg|RQltG&e(PD2#v_uGVd?9HJt-#&ap->IM z%vr%MXMKcSU2V&HU@j>oDH#%>g^pU!(CxYPCv-|D9EYfQhsoXA&gpo$w(v5l@`oq> z#%CV*gt9QCNO38tYqf1=z1obl+PLEKs+(F;IcvF-onNou;9qEO@6|T36TY^P5wh6q z6+4&jAjEa>5KE*)TBo11Q2(-*zfMUiWTrHmk(Zyh5FHZ_(X5*7n@@XHspnI)*cDtL z9eGm;EDH&X2#Sy#9$%??nGAk=am3?lG;_DPUS6CulyJ*u*T5Q#{qW5uELv`9q(y?$ zNp0q#W#Rh%-QuoT$vb*W4t1+UIj{mw=X0gidzu>U{POUI5wRL^NwBtrk1gZOd__1s zj5?cZf}>Z5&gJnOVON*8w>R($`#z%bNUetU_3&ip0>6Qbn30o)$0l#2F+Ydx14dn$;hn(f!jVPW|WbQSAOJFv0SGM7|QFplR zuUjfoTT&AXF6q|HUmSkji$RZ`tID9~HIQ;M5|{4Jzbgvoaq_YpN2MF_|ajJ$!nxqo@4g};T35YK!BhhHS#5Fa^0eY~_))QR0xvF}`{QwfcQR`2b z2KMJ>-RO&M|4?x71Ud~o94ss}G&B?(6jaR9iw-;Qh6RR=cp#xA_+%y~hyU$B^@LL5 zqc)ONtb5qwd3&?+@US=N(J!oabyX^LzJMe@H@{R&9k;&Qc==Jz)U)k|o1Y2K?1X;B z(eSs^>2hz{>1sGY1e_Qd8JdtpjMVscTw~CsXolYQQH!WK=eAm#Z2Km_uM7z(QVJKY z`Z+NsC8gHE{Ew!j+bY&a<-WuQLIQjJcSjvCA+}c!%uPKI5+5YL9|4N4;1xw%FuiD2&qCkN zfA)g#<%D?K_;y-~oqM+s|2eb8>DNhl4YGC|9E_8*_3Pg#nG0jlkdS*srj8EB>(eT8 z75vqc^PKy;TctVXo`*Uh74^S`c=mpEvf^SjC=SjTN>amvzt3pWSdqc_OfDX@IV360 zig>FJfmT?kTe;U?v}SAM`h9q)me;z{c zzgGem_y5Ns|1{En%lTgw`+qsh|2*XF%fObEF5!RrzUvao_r;SKGqi8Z>MH_Nx-{Sk zl{<691mrY&vXjLwt*xzXY{=xvzdZl56e^kmI-G#20N~TL2hKNHv1RL||KlqTQefY& zuFdxnR5*WukHfRGvx^J-=Znovg2WLa6hCM_l-mo|SqT5^L)jjP)G<69oYz$j$Ps9t zzdBG*zTZs!&H$iYzNoFOO-f3NKPzhDpl9_u2rMHb zfG+X~Q2npvfaUyhv!@mkz)q4-)j3g2V2< zTX$2HL~RBBmTz+Yx~ZCik4%0M>F@Yl&RkuFV;K4iv?*N1KzHme1O|F ziuKs*P-XZPRklM0T29M*^A4mAAWmnE^e)l%b0S>2tOt;sq)Y#RR zg2YIpi^b-h*)ij{MNb2vuYHjh=3^rpwRf+11@=}QKT&Q!kQ=V=qsypXm5mP02E{{y z7Oi%r5O?s^nRebn&HOpJ!d)JmPcokXg>{QWGaoIO!IGG54$JF7Wp2Pn;)IG{M zS?O3^P9lf`?sKEU+kEc=Swx^|(|732*JGGl)>&EqXtS(nuV`jWY}rloWDXpUWL|t< ztY$aY-yiR$V$I-nl^cihf(N;K-LFkAQM>3!C;RnjpjYgyQOhst`ixqO3KRWE8MqYo+8MJBiU0` z*9o*9a_j>WxMMOh84U8qhX7A@ULwn`_5sFQ76z0#v@Hw0Qq=Zmd4LW@_WAeQ8#PO8 z*8!s{lY@+oiVXhF%5yyHk404lC2j2~)rHB$bx7AOVEFpJ(0LIOkyl75cLz_onqf)f zx%R(53$!XfuFoK!gkET`HyMmO$$>yMTcQ?!Dle+jau)FF!R4}5ormV^-!qVQ$Z6rV zJsSW?i7@az^7_8fN+w*rLNg;H_MtVyX9MFEdST*GDe^|Bz4SIMzK?6tJ!F{ye@L2e zsm9mru*mBwaJr3*CCqPi{l-GG0k6c4mg~({xda?G(aG)Jt+^ppdvSG72g4k^;~FaN zB|nVENLu8Czc({1tIsQd+eB)bydHbl>Gb8Cv|N92;gHEVJ?C)@2`mY0+6#*22*~-v zrD8!%edGfTf_U41OuR_za5!+r*4C@`6kI<)0}D0RD9O0ksD66PkhtSLAsZ}pwPIt` zeYbnwUa;3gSO;s;u`9D`20{` zu8mvEM8RP@vLvD+K5UUb9GPKUToyqPR9)*~wVj|5j-M)`E-_C2EYrX^qpZX-&B%nu z+_i4|9#fm<9+|=c;68sVD$YVP*ln|ei&~3Qs_WNlpGIcjWSH*VCC~BkGQ#dMa&s!m zxw{9Ad}`|2=Dxz80F-fSN%o{cA_Auz3BBjd*tVn6=ej-LwYw6{cwVlKN*Y=&&y6FS z#YZH*4m$Ojbp1rybXSED#aTxrByr?xje66419&xlm6a8Ak&1PS;&(mF+n&0fP-B_2 zS`v$gp@I~J1*Pd0V60+cwOpJbV9?RTC*8ko;6iQ6p7&OE2NOF4$sXpdiKi9 ziis+6KX#0sck}uszvV#!UHk0<7Z(H9G|TJr#reM2k`(gD5+?qyQemhx)+}veVX3rC z``50+K1vL4uj!5Xsd+6|F6EjFB_o^8u&W*4YdXaqZsdPbQa|KF@}=oDkTu(E*ldO* zo$WUJw|doL%M5x^!lQS-43Mt3J~TId*dCx$2Zw!DU`S({8&&nC4u|A#^;<5CJ}2AR zi|a-FEXXVE&zkhP>A>31-d+Fz4t<{T8zVgv7n0BECyd7hnfv5s+au}+!tp<(qviqD zSuGZ^NVl9z6N3#FF}Wme2`82S)OJ$j+CiSkvgD0j$}tC@mXZoa&ll7Kk2=U~^wK{@ zV@V7qVdd=sOh}P#=Qc7u;$p*JhlfSKnTa|o^AsK8AL|jPI=sfC7~XJVGx&1N32hRB z_&SOLvW*8UxeLt<#J-oPN#C(3gMp%E2e4fy(sGLtOz}0Bbet|-o><)_Q!?;*tesA7 z2F|vH%STu;*jjA!h6^G`xrisY+8daePcFO4Mtn7uK%IjolxD?xi+|`7yb4Rp_0RJy ze|wRN4NG_w=jBR@$fTWapHY&QWm8Bebh$A{CHjd;K0o^yTvVwupkZ{?gdmq~lyY`J z?@iI$NY}iLr}5(Ml|zF-h+kMCg|r*h5O-->6=by6TGg*-W~XCc8?@WG%+fGG+<~?X z$QJF84?O?El&--Mj%snXm+}pj6}v}e>B+&NX=5%_I(S2)R@T+Cik0fg4vmK;vBI`W zQpN`$NMZxKyQ$|?st(JH0U+Eu#6B*GhE83_84C%MkdzvgmJUM@6~GcTigd;3F}F?{&-(4y?s0!Lg~-&Vj}%Uodw6z|4cMo?TzK{*|Mc?4g($$Cq1Mui*Z#1w*C3q)M} zx6E%&Zj(rdPDZkO&~$n@H%Vx{d>I%Oe!dqc%|{qm>Au@faoXaJdk-Z)i!4q5l$I3d zA^i9OLjC(#!P`q^Dw(uzVQeOiOVO;*$ZkCrT|W_jS>qELh_rr`%V4Nj5dPYTSrH0B zgOME;#7#u0w%NGpGPu}0PsR?G1b^5e1&9cz*QHaW+T*eK)(& z;Zjm)-|1ZZ@#~{5Q^w;HDgu$N%@q?ySIGD8YT?W*3q&9<0fV_c(mGtO1OxL?Ue8lO zy?0^D$e~LZfPMz`;F*;XLnBs_IBKI)=P=NdxPhGg!&+K&e*e)Qi5M(lepOXn>-p%^ zAAQFQj0|1~#E*g+{bY*SzY_YSp}%m}w%{8wD#|6ScgxdS%Sy;)+hQ;Sq6bWv8bq9hhs8zN>tZAeB&w@558~g^S%O)^5oFr zk+GgXjIg|>`o+vDmy7;DU_TfXIK|-vf;gAmn>&6;_S=L*nOZghvy==T##^!K)n*+#viLgb+V6--C zH#(ji`DO<6;98ax5q>i-EO!{bER`%&q&vA)VJOWqs8)afJ)cAuJG_I6 z)~zd_{N|)2rO+@}LbOk<*5=@TTs~Slds=r@qB5aXJ2=<3)Ne2g!^}+Jcd-Dx`U72p zt-KQWkO&BdJDQlOYYvYK6l{1f2JqkIaBHxhb-dMnA}%xJ=re5HTa3iFg8uyp$zPhL z;PQFV@%I^@W!r?*U zAQU_(lv|A>7nl3VuAYN)480*!W#xT+(tvdFuF)miX;lHx&!x4p6@6vyuULNKE9OhX zedv;;d^$s2qhV1&rw4`t_CY8h=_g;;mWJ{TC8y2Pn*eDL3caCJbv7u^?jdd=euK{W zBY}mD>2joCa`Z6w4q09`-D~3H#Ki2B`ry41&j5UfU5*crvET^)1Yesfjk|}LBnPG7 zH>>4T@sP_#tDu16wQ44cC$uZKcF&9es&>SCGHXhQoBGxDynlCEU6t9)y$;t+DJfB>y@Q)peKwiJ4f&17HVrrbd2gdwkvX-=@E~Fh zRsyG%XN<)(tZt;V2&q4Nbht+2S1XR)THC9FqZZ9s4$K@G?VS$p#f3%Ls_l(z|EicY zIyvVv&Fz(H%0p?Xqu&w&w1R-vRDEDUjr;<6F6QdfEVuT!-e{80%&FwwAoGMwKXo#v zMfJjTP+S`E0goaON`eO2Xv5%;HMf6fOCC}W1wT|V;PWoo?_YmjA90^wcUCPi)wkrC zhMAybkE%9$?=Eax5Z5T$#v5tvNuaHh?Oo^5j>2jspme=?cUODAN%!5S<<*v+vAajo zXtCMLuDbl;^>;(ia;+uZr0PaRX!oo|VM<-&{c)?PXQkT~Ny}6D<__lctxiVzb3P=w zIk#hjU>pocx1+so&azqM^&TFV`tQl9X7;`id;C(Mo!EqBN(1*X7+ zmE}s;7(HX@Zs7y`PJa0OS6*{DtHKSS+G}m-CO8YbU3N>MMw7NQcnMAmp0+EAE&-eYk9e7tpWjfohW#8c!w_%dU9$ybj3Ug$( z*J7R@NGl@GSJ+nOr$rTHCdS>z^1&Z;c-*Y+wo;K*=uZS%Wd!c5&G;3l|*LyZ^9#)5q6iH>azE(rcp>t)5}KhzZ(#l%X1_9CCA4T$l_cc zN6-E(oz}g`0NV6Ur;Ej;^~9p3 z+aZo1P+G{+^(xh8ih}0Ht}cuZvHt380~2@bhEfT~mfyA2FE1+6%#V#sG%cIq1K)>3 zD*#c!I-7{}Xe{NGFzVGkHXr1qeS{)z^or=zhcRP z07r=^Gn24*+&NYI4}STkBdu-bbJM*!Ia=n-d4IamK}<*Gz9&!Tn#`L7PM2@U;31^D zn%|1sau0BaYlla~KSm0+)g8)1f7LW(a@2CVoBPc`%*o)Rgp*IeBZX?=)?3ww<{dRy zK9ZS5WNfxmdk9!;y|1ORn8RptnTPowH*APc(|qH(MVcvz9ne`$p-`^$De{ z2=7L|nqh&Y%sTTZm-NmV6Ok(NDH*%|bgjj5;@n(ghKPF&C+^BBQeg4|l01v8+o?45 z;o57@qsFMYal+w2`?Q6_RBCeCpHZ{FB-D)~n4p?0e`ntrl8mGb?glyOm~EmTbmWU9|kFN;cKRb7>E}dR0+-t5Dkk4U!Hm{s`GADMffD&Y6 zkVE^9FD?S1fmx9b1Sns=Jo#ivBX@Uh%uoP>{tN^0$s6#-^6J?FO!a;wO9Cd_fLpE_ zfJRFgJ!IuO0@Ej;ug`SAbt+4eq4S~8(*pnkJ2Nx0y}dmmBBDKjf$R7O1O&9Uw)*(^ zWMpLI=H}McGI{?bK!E`)_T=T|U0ht?;NSq$=YN}Zq2z6LZVqtfgN68n7kOaQL=j@s zqzOPHYXQwop~1nZ0P5=v)aLS^rohBO5+OhlB|%G;gaRSFZ4g#Y13mMl{NcyfQCS&B zmQ?OpJt!b5qQ?*l79m2gL+HZ^u=s=MTym zIvm0uuo0nyyL5s6)u#qvPY#0!0`*0{$^|?a%N16SRSh1e7b# zlfBT|=5F<3Ba;Z5pkF$mDp~n0$M_dV|Gcxd;PE;mojT;lzIjgl25)==86fXVk4d(Z zjya}*)5_uCe^IK&s8t|klkua^DGz>DDUL)QJOO>1cj zKJ9EQoEi|bOWR_0On8W?%ne`AQL3N*pm3Eh7Dw7A_oq?YK04>p>z=*RACOGunX$ZU z)?dJX+pzqc_+lqo7~&+bhy0VHthu7%-FJ=^1PNdo*UcJa}Lv{QLZ+!aDQBG!6%;c zn4NbQuSloVP?Hf&8|Tk_96`wqTb^pMt&OfukyAeWM0b9z-vRO=nq1sHjdC9b^F;#r z+i-6Y#@=pd8$6N?FS{cetAt&U7{ML18_7>FGVBkBZ;X*MGq;I{x}H(SRteJAur^_Ze&L$ zA(1x-Qb2OB)Kt#=ISU~)>uCscT)V5oefN|ZGH+|e>7Jc853{G>1f_7H_!Mr!x*`u?AGopB|J#jDEG{VJ8;|x8roT1 zsus71FeIuy_x^c=GZMpK|BToE=>Dx?FEW$m1`Gu7diUNJQD)`j-gnpYN>nZ|I?S;Q zkY=_=_wSHu8}1NqWg#|dqhXTYK3_;kgoK!JxU@Hq|88<+qocFk8JF^(pwd=US*W|8 z27&&tYLy)UJ6Iy~Nr9e}4(A3P+EKjC*bgvyfvb&S>{Nw-_S(AH-A zbbYoG8A?_B(%kVDCt_lLTrjDs!%WCX(dO%3>mAwl^awodSO#|xm4f&?_opak%QI&! z+qBHJ#@d(&L8^0ABXpYU=RDF9@_f?Dp4Y8&kOj!*DSAXA*$L}F;6HuzJQ07ctD*A+ z8WdJ)yjt{_HhH9v0S4Mu@1IJY(B`QnwDN)b%fs7dd$2SR*P+ynW8|oE0>TCT7}xLF zujRsb1qZ?WQ{sg{$8l)f$oYL{B2YhSJ8nq%627cxjOy>O0)9 zzUC(ti=~(vLUzV_tA+8@ymWBQkiYNqeXo9$=mV+C&HaXWO;$Bqkq!2Lv-7K}yt{u* zK@~B%c#4=^JSd>tuFW`DuBDjf!T(&i(elSe!g;enZ@nA4v-3ozayIcJDPienXQQTN z|Nc8Gu`Z>ywR-KgGAt)v2Xpq}UeV$3nv@ov$U(=`O94dzvuq_3lSN!=V$w}dvA2Ah z?je}c@gdh$3eP{N2zz;vS``(A%`vM_lwFSfOvs}s@S@E}gaYEtve5aVepkS}Ko%g{ z7#&{c*^(_s{WhG4$mDX~(G+`Qm1(nTHa*vDdDy*5#mkxwOCI6Mmy{EVUUsY~-smVf zHFW1TTzHXKLgj&yHy}zVG+}hNS2wkrm5;Qpw^{xbpkE+z(ZT+M3D@j$f6GZk-hb`wAQbsf5{^yMkF%MB`>kEhF+#gdhmZ+nw;+<0NQCvN_)&a z?@eucW63p+I?R_=WV9K!=3`No6?VCZ39gbUg+W;=N|{^^Mfdtep)GxRyzcj{iL{%F znk%TyR@wE6?maJf>URX_mrp&l9-G#s&EDf4;_zZ2gSk~6hc*>)HB>E^ha9#-pI*Ix z{xgSC7iYZK@9I8EpRYuBzJEV7Q#y*<^~b%ziiMdq_w* zm4aof$#1jbHmlz~udvS`&`-Ld5$TB`UUi;MCbcM=y0W(F+FfUBDg3&l$?wp5b7hD? zcGZ@gN=U$R>W`gLBhu5B+uh}4Zn5&+2l|Run`p{LuO`oXmm38 z49yW4&00IY`KRS96T`6sVdK&bKwhYyi|)nadjhdZ1MP>NmYMln%LwPaa2O^u$m>3) zrz=Bx+(Yc(;x6#4F*5u0y}v(TyuW?C#6v$W;#{qv*W`M-H^)-%21sL?f%(J|*=5Y& z(i@*^p6~2Jox-prn>?*$zqJ_e`=#8Id+#REQJdRCdn!}~TW^oUEFj*OIdh=2!UV%+ z(TV*!@o4!%3ux?-2w!I3KSF`MtXgMz71|wCMV9#;Z0M}9+Rik_$uFbMCKF8{(ciQ( z)Q#@C`h$|Tpr6R#C0S=x?8feuEl-mslFp;8xu<8r?~KNgN@!C!mb~1$9}#~34rIJ* zU(*^}Tl?8uHEe58L*Oz6$Sd}b*K_;>Lz=;4zt)g^XBrgRmoTItE-B+4HYiPw_=L(i z>oa}({+Kaq$Y&OFohi?xRejM;%M(klzJC!%gAMW`9y*M~GWo@5RO+38^KRP^-`wCB zJL9PH-WkJq6*eT9Oz=?zmeahg#A=2DQi82cK7L@O|3Omfm!A;Ui~|}2w@%D+=iA{nMt0P8GSh742W0Xm_LGqy0t0%^hCa^m^@{VS z^DKg}YM&s#ulRhBI2_QCU*h9m>mx82wd(GK$-fx>{e9KWT%RdzjsqgO>*tV3D=e#^ zz(Em!;%H9}ot`+*HMkN)lk@1t$(+>9G|{g`F)5>Lhh^1Pv8zi=A4g8+LIVfMYYm+K zAB4SSP#jU$s5=l6T!IEC!Gb5aYl6E5x8N>=OM*KgxLa^{8C-+AThIXphZ$h7JMa6Q zQ|DHlx^?+MQPo{^&vftIyVrW2wN9+@wj<2`yrq)4QP?4-eLfm0Fn)nBE;M4LeEIj* zh2nj#3Z&Ym^ksgsiEdw(an$N!nVP+lO9CnS>5`7#9P9`dme-O?jd6arZ|vBpaLgPX zfrl>H^=s7J^`5N#w{f7tX(D8}`NRiW`DP}&mHWLAhczPkurh@ZEb1azcFZYH_mT28 z`GJRCy-Hq5lG9?CDg)QvjgvTnvGIx8+?o6qu=N!xb8I^1+^kNIvw`iU++w@7hsTj< zo!Cx%>E^}j;2Si!kkY19Az|Jp3!xnZ^jdf~o;`IX@Vwp^Ep3>tBt{Ak9 zG)@LIW7;}JPICo){tCVssEm%dposrbEW~$9)#(9&fO%>ReOz~K767{aLLWz`5OWZ< z6E*ZMj?nXVnsy4Jv@VH*=uqiX@cc=`1!TM-T2CKPms2gMJvP7Qw2=U*AyhI*nT(Hc z<$heVP#}AriV4qrB=MT)TzW&u>d$T{LT*>`c+V9V@`pR<6+l%WOBsF}pI`7X{PV}X zX(oWl;9pL0_tq;K0{Tl73JElTP6Tpq?SfEl4NXZ2Z9y2faE-6`{w&lE?6kS!YYA@u zVWGk5p7c3{36oPZk&28}uDF4^oQ#o-g6@Hv2ClTC`m=(_#Mv(19R*GhfH<22U_bO? zQW&ms=7o+GNB1uuEvWEPfUfe851bR{dD~)H8J7#;^-U=$8D?Edr$YZsP8EBctdi62WDC zHLQwe#Vm2Bwl$k;7JW9P1ZoOOMKEr=n6zpes@~pRT^b5RTTW)T znLGyx%&lkXRLifs?WhGeHvU<8XULNv(q>36kWS8*eScFba_uk! zVVN>&^7z$gi6}ob{WQf}wGFQmM-}P*6{Gz%^Vg}40=uLB_xnU??4Z8oNTcVG*I&O9 zH9k)+mKQv&uq4;w&e4|8L=4c~hL9M(DB8GfQpUj=v)<|6wd;#L%wAWgK2$Aq9bxw$ zpjoqG0K^FynHeRXpXC86AEF3ky*>j_H05!vme~){h%u+djUMC?73^}1 zgpU8j9PWI(B1^v#XC_%@I zBRy>gAM&>M;$jBI9}D9}i@&Ss;%k4z#zTsXVZ@WAc4`U`b?9hqo$U|#K|`FlUg((` z8B3Z=oY?s=-6jQ6-;n~x@M#z0U@dwAv0#CTZE}8CH2*Gk{DR&||Be}Cd3MKkF(Aaf z;O9gSmyt!Od-;dgON;yi571-snF1wz7e}n)TcGFe+R&AMQh>M#L-2-?$itBG1ldKP8>fa|@3$_|mx2M$6ltiMN!b#=J{ z+OJ>z02J|X!`yy|D=TJ25BhIhJis=O4)0Uc(ad)ES$xJE)G(LElR6B;ISBVc>806g zc@s)t8uAru@3vx+*^f?6NQpbX!#~n`EF`+2UWeyg*R(y9mISj~h&nVjrA99X)~Y?G zfbZ2birJ0oE7S)BUG4nW<{Wyf1GQPABJjS@7Yz*jA=1KT^(){NY4dHOG0o?e^mS$u z5`2Gtqd)mlnm04_I6$v{py0~h7;@IJJW>{wA@Dq0Cj0I4hahACKR<7{__L`~q?{Rw zVlNGVKTbS~j?-X)4G-<|+m{GL^%SHY^ItF4JdF1>Bg$y=?*Y>qZnvAkGPNs||GASm z7Ou>)U)IaaDgAVc480zoRIT46g5hlXoc%`Bc^!)ghI(@-o*GdK<n|6m>y;ZXh7TWnKnw53L%TQNj4Q3YpCFO@Ys&p+8RchQQ(a3uyPZubW6?(| zo*@tTiNG8M<>^UPEW$5jVICQiHH+A};1A6UObKbM{6mrcV^{&1Gv%i4r`Cp_o^{NY zW`6>93x=Cn|C9ERkzaLpdwQj#y2+|EiNE3CvfFshmRo?irVb7;(1|x zRHEbR9_Zz{`t=3jS|Vq;=Oph7ZYf)==cd7$kDl;b%N&4KZ>_Z zVRLpaOyz6{CpYXqHegTzdi;LJwiKr014QDDPr4uP9$tU8RmpA*XfOaogzX-z3YB4b zRs_?Ovr6~ui~!I8;iY-k4&mAPBCHgw%x4acWR9&edWMEd<{~73o`Vtj1dDBz|B2$z z9YRX@h&R}L+)eC!)SqG3HK<+BjaPlJDoBHhNI4Q`hPKA~@EUm_^9dD>+b>>me|YI3 z^l2v%=$~u#o~7)g&CysCa!)CX_x;Iie~!wjLXrON+)|N4`)#pBUKNJa9t?Qv_hcAL ziTyN@jm=}2jUAjVQgu#djo|g*`4+ExP4E;06;PXs>i0G(_y%uLZ9W2i#Jl$73hRa7 z@bb9xLKj^Dcvx3Hha!Zd)BX$jJgmN6{El6TWgEXYJRwNa2JbvidM-65@=-hChkl=R znRGt@phPuiQ~^*M-!_YI4V}S|0Ybid9~-QYRl(&2xE5_fh$_uLm^ymksho0rWV-TMU(trVh{xY{@tXM)Ii;-QN>jT zyY2>O)+$6f?Ec+{wJv0yX`>-I8y~fZF5hNSGNFjm003z3f~k#C__R7+0o+4JrNs~GYB65Tp; zdlk2tWz!{LWCWW{TZF6?96&}!$aE*-M+CLkqcm!bIt0Ca^;)Bgmn-I0SQwc9p>t{z zFzN|av)R%5ysk3h_pkhrw;}wCs?$ezc5}GNowuRzaJoIMP2zbaRkRWL2j|$?+15Xv zA=mYoubJ!{e#X}h5Hw|%)mA1J5^urMNM13K6yiPBqDo6h>qpMhzsckrfwRO5w>N%9 zH?AtLFyj|M?9)iU@HE)lS}Y9zX-*xnb6K|Y$MYrp>RD67TK8x$GKcq7KBd|{kjGc% zI>5ZW-uN?4t<189T(DX&(807=+(@)BYG8Qy zL-}+!UlkFS{j{FWbuvEq=?7fUx|~>T#ji0|Mt=T4CKmATZ^kZ(g9z~0?*Lzhc7`O} zOr)t6pNv>pIfa21iY+twE!z#|P}8%}8;}yqEv)+fFn3n{d2e~~<4YS0vRU({@6FwI zHW!3|cBe3rgBTH<2FL+33g-wPX3V~SW^)6h6EG~3(gFacb8|5ZZdR%gLSh(Ib7 zRsGRWS`kfY?YY_wFCwk#TQ`#slY0SY_nw}_kKnA3)}3#RU>A>Vr(^iRJw56~(-NI( zHRWg;_^j4sWeA%Fl!hT_7O@|G@;{n!^+wDG*pt{?9^atUpm9ZBi@Ijg{OhJ{&pj*k@aYSw!IpOUt!#6wJ*qs7<%3o>q_VrBY?(|-9bQQ7A zS!Zq2ZXNw-QdJ`je1?_kRAO9?OB*se${bD4{5_aNZ+puXm|lsOEE$Nk-QGbnZv_L| z<)3P*iMqWXO3M*?HUv5{FE|SAw&kFqV{Z82w985k}V!Piw;TL@s1T;fQ?pv zsckOXo^4^DhoOifutsq7efvMyt`Osa-xKA3@P3rst>^ffl0t zh?@L@KlA_+Ye)&@I5!aRJaLv#*PEQ-0((-A%gb-L?~OumlPx%mMT8Ao{nINVKS=k` zSu5Q@S6pC@x?deEEbN@@9PS@danC9K#$yAUnt!Ll9c2x_xZW)H#G+DbHZ~=Zh_$+3 z&TmiH_4^-qD>pXt!bcX+)t2VXz1^<{!{ZgU{7bFND{9z$ZcdI9HXagxt1o`3mf!Gc zyfak79?iq%?r8I)8?p*J!&TF@{j>1cn&la6=+IQu;%Ky)NRiSN0Qt#9GI{cMwZrZ< zB~izz!^a4Aw~+`UDYRTMwa#VdC6tEKQ+zxt;no)M_ku27Qo2BPmRi};Z3}K}+VBfS z7AZO&eonr#_PagaJfbX<=tU=QrVLn{?vVm*t@H0WmT(})tD(WcfB!;aTrk!f&;MTQ z)UZ^LRoIQn8*M6JWb?=q4HF>)eq=m#WHor&tsWa036Y(M`dG6w$o12*f(Q23YNG6f z^z?lY*dB9K9QBCd=MCxOU4Mym@0t7CwKD7l`rGQ9P2*O2H;2hcL|HW|;YN0Pm*J7{ zePD76m6)Fo(6h28dOe=9wvIwHSdMWd<`cJPjzD0>i18^(se=H0!M{c5YS?l8@p17` zRC{~IA`AwLgHmtf zrLv}q#ip|2SrztZVPWp?uj8xZYo)I*V`Z!&qi<#Bu>WvefU1vgrTppc$^cJVd4$Ug zeBY8CQw|mV-28R32Mr z_X?>elIh4g?wu)b!1|q9u{15W`*$KDEcaMNrI?}kmikQoiAmSSoVb)7W6-$T3?+~E zXv}@iwbgi9Df4AfMN!A9*DiW-bMc$P7;eHr`X3h+$wSe0WXsDSW!P1gkZ;PE7XfV< z^^gKV!Ynr>_!Dp_W~E`hL@1VTdbY2Z7C-3O#t-miUkfW1TROhs6E)xBw77=x)bjT~ zbqT%JhF@L!hUd`2J~GtMRpsT;DfjtjDJZIKd<)!Lb}=7LhcK6wkCY#i#e8ZZv$L=? ztuA_o?h2ae!5I<_tfp>_{+*ZN9Hi{W~8 zJS!$T%2AweB|He6Inm9DwwiFy_%37{a{P%=$7rd)uC zbzuAJ$W^-_Lxvz+dT3StcgE@}#wf-pf;pCt;&hc~jw){tE96Nk8m#k5*tQjX``Up# z)y4>ucj%6k<=eBJ#Ys_rYsi5G-_ESCt+(QAu6!N-pIr?xixw= z*ONMZ2m?H~FuoHBtZc~np=Bi&M`4DQXFu?`Lnb{EWkgMf}O^XHBw@WI-+L7QvY|(bVY{$N~vf;zhvnU)X#q$QAAG% z*S2?9(z?33a&idoRY6KhiU6@cNkM*oesOUz;&)LIJsTSv1A{ajK0-y+($sVZ0>ha_ zzCjTOhp4HkB_PnGloZ4PCG+v32mc368bo}e$S-{eNp;B-06>Vmp@?rR6idraGT-@d zrE)6piyC2gKekrb|00~=cqs4jBc&230X=4QCeaTyCZ+uZ@x#GW&i{dpJaP6ey%5wB ze^x%q6!|e;wEVn_NPSnG#j@%!hsuTBvYRysO$-x3$n+ zDWZi(f92=!N$@2i&5yLc@*;*Ff_PUs9Tw>WU;eWT%zv4a$K8KLc<~Zx8$R}2<12@O zi}>)b0MD*ZZ2w&O{c?U_KBoqxAYNi}2e&cqUPefq)q2ca0Dud_w*QXQw+*)w!8d8* zeB^GglxSJ(d_8Z=CN=Em8@aKu9VCClHoey_oL2Cus*bi7g7zIJhv4n-!r02<$#jAK z3AY1o5-S;U$jokKm2^CJL(XyiG{^P@w1iTz74otK?QCx~clcGcB1>xH&%#(?F_tos zwj;P=QP5d+>IM0{NI)?}nyDY_nSRvtiOK4`>0zOEAn!$tnQCjfiG65O+Spib(C^RY zH;A0JMBZ!``E0kSwNXMo_Rjb`2{UC(jv2iIyy6bvB!k}CT6R?>^bDWp1zz^BD#xbiOM6S8jdMzmL7JQ)k(guu#!Az|Uw8_yRa5EaJZ zXozwaX_`(gAFwGm^j-JWb2^JoZc|jOYy7CUq2A@$!tSdz?T2^KouZuqkq{J0LxS#g zsq@w6h6DPfmthW?XN~}&x{F+ES-U_l-(jDr!LDby`#=j-1a-AFo?1?Yv~G&;hB{e%5%WA|1JP-XY`oFujTyWOOX}|3V=>JL{{*UCaGRj9 z@6z=|?tSek4l?bj0kQ_4<4Qdn!@7oUlG@EqZv`W6-07;vVb6ZJ6LTOhNfDwEM+52= z-?=DsPvUaTlkl^}n(ogEbH4MHgigQW)4(h9$Nmh-i*O?Jz~!kon+D_QLcYfoxqCqk zw}e@Jx${jO9Bctkj{`HnpBUC^jyHWHi3TYQXDqvZ>HBxZ7jotlDRg^=0VAH@G%gOm z%8fLTaBOwU>1}`Hy|B0HlW%xSYesE6+~oH(?R(RSePp8ZM{6fwwtb(@XUm3 zMpBzJ5(DOkW^u0~4kxOOgimX>jaLyfU2pBCguUk^Z5+<6B9V7$Sr#=PVP_jrEfY`3 z1zmH5ZXD+$)o02Ym2Cbb8Dz58Lh_E;onAF{ub$=qqpQ5wdRZvMyTG(9^#lu|Tz$d{ zvn-cYC@NTE57@_4ODf-n{bt<8@4DA5p|l<~~!sjsu<5@tJ#Uq6bE zufEI5`UwEQ@{XCC{ikFVMlU-~Krk{z&cle5PUaP&otg9f zSD+B|Ivfq>l}{$~n3%BtTzdSBBaS6G)@;R;g-CV3Z5V75CYbUFFoBG?EY)_=}Z8mPU`yW4p znn8$)-QHfgLtoqYfB5;+FY3bft|B);2yOYQg(S!O@elFh>u&6<&;=A!D~`2Du8CNl zPk{G;vkE>ws`XB2foW@h)WXfqNN~w*^g}DcwJzW@8zNLVe=W*RWq#3LbpG5vyJiJ* z+Dys>Sv+j+rbb0)pmqyt)cFY7%I9=>L5mynyAZh@P)S2u{?0_^?^PHT0;+xW=Ary} zlc<}GDbP?&{~^Dlu54#x?W(+4`3L10_mWUg-zRSaWWc-A8BESybFA=V$IF?;=nu06 zOM>qbkQ$CR(^+n(QUW&p1oa~jo-k8<>pZ=J)yEO+1s8lbGdIk|Di|jr()=i7?RJaf z2=2Q-w#&uu&I&Ne@?Edr-%jySmkPW^lV7Xlb)WgBD}L_`UB7(DU5eQ74)nF3gpUh~ zC$;GMKV3p;7?seG0beFuFwInQHpKiJxet9wGT)_pbRD`07%vl^2ya@b{e@d5k5uq( z2zx@E{c5>%CCe-Fv)}Jwxo!7bbXKyT@8@v^w^&jIx}6-343zTRr|aH_;|vt%_^QH$ z`RLgeeaq2ua01`|r>a1pfOOz3jRMU-)s>Hl5|H!rCl+ir|9w=xJC)B`5(B`A&PR;+ z^{R@>fagP#8%YjKC2uafb3?1MM!&>=LR8tSodNrjcIFSE5Las90An=`KS!{hC#w19 z&r0CDN=A!L02*pV%_+;WS}S-uc9xl)%4FHFCEigEEsL5cxed5R=Jtn}_a|-!tvB!@7Dl3cv5&-vECxULT#OHh)pn#Q*9nzgS%nXAt;YoxcN3 z?<7UKR*acvr2rFUd0$@ABr*^gu2Yipj;(6y=*lTeO?kkAN|j_BlUle22LJ#RkEO9; zFf7DJAZ|fpZm~J-lkZ?${~%jZ^YKu@t4vOkc13Qg3On2LR{QOO#JWFy812gW#n7VP=7ap>=7aJ*bl}MYymStL0{zq_=;EYN;=~U&pp>yYv{t;H6uyU7gdO)r-S9lSuxPXx`xtF8vNOsZ zK3%lau$lJl-J_2P;4&XS-+U^oav-4LM?|78zulZsGpaV`WV=0jJt8udfU~SgMFqK< zm*e`v?Sq`ZgC6`}zG!=@U#wC(k?XbVmwQ?cwtchyD^JS$4Ycb323P!A-59B`@+$d$ z>LW{2c5EHh3G!rNTBkL+EQonbBvH^u%VntSYNYkbU{hOhA6;(>XBT!rC_)#~##TbF z5)yFcXx+AYVa;3Oh87lX8gn$Tm%7_UQ(b$9t(T1S3ZcU@JVkjFA+G8t1me6U1~ItzfnT zb)SCsAQT0?t6dHSY_~E5FTKg~y>08@yj^JeRHL^0CXIZhavgYSo{9_**PR>=Q-S*TfzoHopQh8F5G#rtF&k$N>wr;0}eCNcY)kptR*$eU1FUbbxm~#@Xgoe z*4?KxRZMLGjQ0*rcz_8tH|aH8)t6kN^9v^Zt^FmBc@O$51EE2K`%ExWs37@qMkZov z;@L%d1NV=HL>U`(wP*9=E_;8i6U_b}&KYzIU?)n6-f1J<20t?Js zO-&(Q7~&YSwSykK?Ck3hT?&ds#ao$b_m_W~8QSV^zJ&n+h5Cd-J0iUGMq?k(-tN5XGs z&nVZy){6I!u#B3m94^nCz>Vkq%Vop&Guy)&Nkh9Ia2Rvqg#2KSgEyY(0Y4#Obwz{e zk$lu8?#O92yelm5o*cZI&;9WHPuaEy6nHMD(D0K7PqY5u#g#M-w8LCdtuz#cKX@OA zMhU-Tpw|>UY-D$gOn4_{8T1k$G0QCtG^(_={OR_|hS%xJnx>ycfS^~sgNZUb?3+qT z^89s{wUgl_mpK)DuMH*;A^I==bzAu)I#X?IRM@Yk7t{xv(%J)_+Xb43I+d75Mi*$E zmy~Pv4KVWNj`TghQg4E6TALCfh?R-T8B|~NtKszT)aRY`4ZaVHX%}}%Syu%Gv+a-J zV969EbwXh=vPQ?1bgn_7u$40P);^2VU2=U40r?gPI6s`V-UwM0 zY!usFlX2$I=ki}S#@crCiB{!x@IRRw>B16OBr4e6HAOBxuJeI5d|oU}f^A4^&(}kv zU69NlNPl85>6+h}#b=I8apf=?iQzZ9j{fbg*2mK=J3#{Ei6c#mdAT?CPMW`&;`{@c zHhMnNfS1%D)sFVHM3$*=5&p>MqyI?%;JrQ*yp0-XwHGM3FEC=D>ErKth=2a~YSZOy z&`A5g2!#1$$`U@>eykrl+NST9Q`E&$Jq{udG>eQyjHVw^cRg*3b9~e)ej;wyW%z1x zLx~{pq;a7BYN8vXcnR~VOUzQ1mcFuZRjQfx_L4^%rq_prysDDOs(eeKQHxdKrIF@? z(SttnrRohY_m?#`vG2kG=^47L;)s^<#nm~ytDBNDw9gl1>hF&VX1fz+fkjRYvjoQ7 zDM-~&#g__Q8yyu&A=l^QhILHF7SN&W)l|5T{c;D`0nq}S%K`Xru-|usL1-IE6=UBE zn>@Zs=z!n)mMZd(P{78}L`AWXa?8xNo}xz@@5{wm)h;U8)5s~FE~}CQHV+RrGwFT3 z;?=g#_lxJhQ?Y=wxQ&zZI@6HjrPE6~G7T-MuffWQ7i?3lk>O!+hRAfi3!w}DtFXsFKoXyLCA z4;z%HSVKjIYGG)-9-RzJRBq^a{cAw-2ogZNf4a{y!X}V1?hOHlOo*}nnIce0f!#3A zdeX<4@ssP=>Ek9(`Ex#_(E{({K?nbyNbb|%`;h4*193towYD#E3!LW;qBLm;7J52Y z#J&yB;!_#Fc=*0#!f)dwwN;4hXoo+Y^X_u`*kW-q^cSL%!3U{zOKixRjKf{mU6wK- zk$cJ)c2X>HW5?IXu_AwGCbg5rHHdys=hW1(@{cj;^MZWG-~H`TaBaX>5%GUKEtMPu zrM7u1Nj|;h-AzH^ppJT6jC;$YW%CioEK#$h8aJ)QXM{$3OFmhR;Gil~)TUkpz|X^S z?cm#29CLSk$eAJH1f>&_G33Pa(A1n?2oTvE#Re2^G{}zqd;P%b=KI2=O)P@07ft3QsjNS>(2P8oV)KIYk_`*-6mOlGR+ma!;QeCgItOLT>hKZiRKqB!$(~U;iBv$NTV z{4>epH}^=6TPz}JU!%FsIvV(<4Llr}=z1qlU5R3v1k>v`JE6N(n|H@HAg(%`?HF?9tmGXe-eDyftE8K4|JZ)0T0DbXD;LBa- zHBW&o#v>2?Al1(m7U=FxdCY7eSJC`U3iyFT8iEm^2zWC_&l##%iHH2-_aPR=8RLvQ z=g%MVmOGcO025@4Ju&Ro#02OAHkqT40~{dY#zn-eDA8*Fwub$DdxDL{Kn8ajBIdHt ztFODf_CJFPfcFD%Beq;qcmZwb6j~ey0$r$1xjhf&S2P$Ezct*$8{(nz_4!3*g0b+0 zH@F%5UDqaipSReav{tz|sIupBktDu!A`xicQIC{8Y>qPPlY5;a=i_TJs})t2R3Dui z<4NYvMSf?)#?P5n&7cUpScX9neNK!UXbumbPTq_r0jZXL8>I&N5H&ca40;Cl{N`g? z>i2#8A>BNZ`Uy|Ez(Q}T3+?nqf5T;!p)t|}{oI+&XY&U;U^V_%2sV^rj3i{Nhq zcNGR?)s!Fa=Pu(p$A^`HhR4uTHXvWqd?WfEC*g2j1$o1=UU$_lpN=Ol=Jzkm0Izy{ zGx4pqqD=3qS;x=l@Bh(I{8Wb5w~{j^fB2LQm>w!%9Pan0%nEOdqd4Yt>?lgUH(A<$ zW}L%A`NdtSX~8cyLqa<4q8xKp32HqSOHG>-8K;2h zP3|`_y7{OC)ZoT#E$Fxa_i@Wpc=Zr(7a9^^Xl^gtB3o>JDa->S;rn+JR!25HQS-n2 zB?-KfyCrcz((N7Y>Dhf{xomuZxT%zb$R~-Q^ibn>S)t(WTz$?;zOQq5L@PNzr|NxqC(MxQD61khm2`HJLYHwcBcG zQ$fI=1?7B8q~qby!HQt``%q9FtnuY!k+Vj6so4yaH(!!x*}KWPt$qxKNuf{p?6P+~ z-&~&c2JD?vvU9doR$&5qKFrGAPn|Ga5V%w(AN{GyO=Q!9l&7c1TL>zIllxX#StU$W=MGI`K{o<=W@ zf4zQubaqAQebpw3^*$-reojkIQ&U?{jSa!n*l29t_v@cF@l<6Eop)zf?C>u+1wQWk z;yQ^b3Q`gYI<+>vN$9bwa;$K;=cSE-{rXJahYN1P$h>mf!SR~(s80%z@4`E?EX2gk zY2`eygr$a$sOQ&Oc)dlJLGlvJ9D(D8fDAU-508!$kn^hf9GhR_%!g}?+MMB&PkW3i z_*4cW#0@4Lg$xgTVy&g@FY7s4IPe(LUE;I0#}G3R{AN&}1Rwv5k=`hN1+;2`m9Dd( zr@gQ^d!G#p(Nr`{VKZzSl?ax#hbOu79_%#e0mL;xAMUxRf7w)koea3(YsKi6;&dO9 zLlS>bX@2>Qbdy<)5vmySUQGp+8c_CyiKsac?2O<45wG8jDXI?*%b(J%*uBNQk#9*J zurTeoNc>WG6rUq18!JZS{qNiQf?Ekk*Eomc+tIJF_ntUTS+-kic+5ZE?aa#lK*6&h z$t}67hDxE~{kZ?l{u;m^A}-Mlk$?Y17-_H&&jio;yCCT;HM%E8dD1T=07mFze7NhX zQAx4L%ls=u2BU$GvUth!+-Wx@77~95%WM%X|5d_gr7^w2Rfq1$z9Hi22QEH>rPz~p zcNQnsBn2-0Wl8oz0epCiCtH4UzK`_B+NQL$tTeeSGe*=IHq@ZQacd@(UI4(KUrkHR3N-Z5LqFfI@Nop4?034^G3ePHWrC_#QnjiC zmuPQhPcv}|5LLB(x%{OahCZ}t>qPL{Sp{|}LIApv_v?b=7gck^w8y$P| zUbTg+!*cCepR`S>lw;j!_%N>KenzN|i+-k>e*rKxn!Sq~v zF$7|blf^Bk#WoEp68)eW=&+|ACH+w7-*`d)^%;1Z+}Ul;Opo^AL><+ zQ8;8Q03TiCoAXyZWBpS*WX3gQ#Z!@0f&^aF7G~$>f@L`YKZ0bxf94LT|Eh8}lh@Rx zGy4TVLp;ZOzIrsh3fMgpW{$f+1A+kF+llS60S zI9I0uj`{cq-T@-$Ie#DE-YdG0`Mg5p8dc~0n0=%^*CC=1dKvtJt1DP8@AwA{a`UC% zzhcHg{roBMBD&ww)w$dN$ZQx^FwSA9c9loEw$ZHYx>$j*W8BlMYGqW_6Q%?923E)o zACjnI`nk~j-p0u%NwG>L*MwIn%XRra%c~>dn#EqPdmbO@w%qr(@#6!26jU)BRqie= zz+?$ODQPL4KR9ye`tRKkUGs5}uNl_}JS@V1VieG%a@6@Bb$!` z-NRNehWO~$($`P;?FzY+YrMOV)u`V=oj-qWe;yV~x<({uR}C+&7SjnxYPRIyE4{K` z)Q!)P^O+j0?_O+3`8GGYL0f4HsJT78p7KdmMWBNdlFwG96gW z#*sgJRbDd3ldAgM=KLl7N02BVTW`Pl*`5o*0Xr0Q^Js^>g%i*s9kMP=RT&7VN@jCN*q|hK@wSe8=N_syM=*RV6PWU4GKV4ls3fG5pjZT8_61`6otTc zf`NH$jXE<|XTbdTlrC@BiJSg8+Rq)I$|+vsTSFbHYb3mBi2$R?O!(Fv7i`<-fb0HC{kZ~L^u zV$0xFdem%bp7I+qF8uTLu7~_~bN~&Jd{JPwZ~nEMnY{T|0zh6vS6g#_$JY<2dAEhh zv%gRNbm|kov&Px1f1m=G?DbVe@^Ms>UpJYH*PU2JBm5z?)xu%i`mQhad>tG6b;1{W zV@p~e0bhR~+z450ao>=Al3+ptxa$yS$BQJ*^YP?!P*45g$?OQ?wL_x$s6b|8(lh~4 zA5Fy)%;vF4urp-9q3-w&g_*~@38H)}9p|vUMv$7{bkvM;ADFvK>25bb_4S_j#`yU- z?}QvW%wIUp-UQ{;-QOKuWBFu~=-!40#lNO^a44AE393KY1GgDZq?IScr6(W}0U9CZ zKH3M@qno>On2AqI_YT+sH=HdJOsomfwpXI5(SfZW76RrBtn4?qJ!9TpN)1&FFU57+ z;6ZT7x;)CCRAF1K?@hIKE_;gD&2`>LGZbBBJ2)7GS&MoaP&HfN-hK(miaY$KB}MJRCfiBU^-Q0 zcK^GBFaUbO9G=y>FuO&PC7IOZzXAXPHOxGhUpFg0AXZqO6LaCzdjJ5n>kR0 z+BI?ec#dPY`@>IsLI6M&5q0for)=^Wy~1XkMFPOtGuL$#8|lrQF#Z!DeZiCf3CX*v zJXE<-f{#gDtLuX$&A4Lz=wh zv=L>yQ+N0I0Mh#U!%Pllczgz@ci5O0OLRWDU(I`;!j6JC1JUNd-!5B4&<1zt4J?DF zhj1$c6u4^uBwMoo`z3dyj+7d*IwTqQ<9pZ{O+^EV8(LlAb&fvzHt=`BqMX! zxuO>*GdO-j9)7fhouD?C0w4YoX0KnMP}=R&)32Uv%Gnd}tN-sG$(dg~5}@0!<2k%( z25D3v|NT|(Xr~UgySlaycJZWKPQ%ADla{Q2Lxj7|s#Air<-PVbH*pfx(b$B`d;jc? zTRgv9l}XpLe;tgi58Ai(DSHP1IETSki!~XL0Dyr|(F((ZYG}Og`t2owTXl0=9n)(7 zjkRplrjtMbteQ3+1OO0b>rz<}aOQ-zvQZXr2$HtV1dZ|>iG9DIA-E1OM>gl+<*H(2 zy~z-i#|2DlCJ@#+XWb7h(tV)+`0W>TbDxdSr4VBIGL^mK+hq*_{wve|xn)Jya6a{N#BT9`s0gK!%P6fT|%R?S6HqD3I zmKJIgOIwl6m%dC4&A`LGGWNnS=hAO;Pj=0O&~xJ~EZlDmj{C4qlCAyyRN@XnQqtq| zT~CNV0V2kvX%&;r?|Vr|AR0 zIU(^qRj9E?B5c4Gn#vZyuQQ2A;Rg4$qf0YWoB@PVFMDJWuqkYKy4*;Y@6Egq)+rpmT%cBqK65mG;=zA-!! z^q;LX)v)A9Z?cWH5?`*nc8aoP3JZ=st%Uj*bCjR1_T>Gb*SOL87~VWF4^D%5W}I=_ zPn#$_=;}+&>Mt-%Zg~jq_g|xi7n4Fs^}~KfKB2AUXP^NJl2B#Ni~PMF!gVz)c6K`8 zQwy(S5s%PuTUK8;$Nml`;uNWrs^wb8xiF{#UnmvmstoBLd?k)rWL_3B_Jes+@Z=0{mBAok|9vA%PoI|FVc~&W3_Rc` zG;s1SkwagW0$Ynm>#IfU3#SGbEoQhkRj*7m{2<*fPPc<;-Oe%)c(6~~<)K;i3@bDk z!fxc{OKblt)}?pIZ81^z$5S^xUYWPp>>T~SQxwb3QbmVEbn?eIqpn1Kb;DWpbyfAm zh9gtciL(x zpY@T0CJj1o>u7F)wtlTk9Rcm#q46}*uPmLGfkHyv?bWO-LJx!enO1Qpx=m&?CYZpp zDP${?c4@J-1XDz=(Kl0HPg_q%Lk-sUv80g(vXZC(o^&)8@~=GoC-(7m$H?E%XH@p& zq-1TvgDxdy0Y6~|(X-=Tg1SsF8}0?HE%^fO<_(lPf`nZA4#DOg{GBaSbQC09vc=^% zJ=3`S`V=duy9`3{8&4SR*PCA?q=}GFXp&XY@Ev6I|(Y1gHBZ19_lIu?y5j#lyp_S^Rf)q}FNi*ioH#U5)j{ z<#eYj6AdoIQxx4m0j4&D!Y6eMb*PZO;gz5``|&kFhQN3)NpnFfRfjl5YauDHeeC*?vMWNBE?)7cb(bBrpmFDm5Hqj=sp$pT8ihpzaf$K%MoZww7RUEo%yevqL0tL zs>z*^Sj|1brP!@4^E@zXxN-%!E8%J+XDFxSCbzj3?}UL^54Dkyc>Y`d8H}ndtQ?q~ z1B1^!6r`$fym_c<qFi{%|f+N5yen$nE=9df@{t?(6Dr%|1(^z8ssWB!Qz- zKJIMp``nPNA}=*=o~8vYptzrVQeY9rPAVVY;5LUNU`kpPrNzS z(zUU%&@k8X*K%|4)&(lqNf{bStgh4+wHw1`J#tzeX8X$*!;0&t;;D`J>zAg4PVUOc zml|BhFrr-vYN)@7SpGWW!%rXhlm>ZwOipArR8*1BDE*FX#rk=MXj_hW(#?YkzP_rv zvAU`GD0(U9dRFp#=lJTeF9YEsTtyX(h7C0rAB=k1412W3oxeDY%EA89Zze2lEppFW zb}EUGweg+w%%IwwM~ek?00q7F`61MkU%r#IJFXwrL3$9e5dueJ72ot!9X&Mz?ccdN zcLyu|jC=$;@#m`@ruDt4T)$!{{0q89n?wYj&&rk(azLg3hpo4a ziX-USb_WR%971q+2<{RfxCGbW!4urwg1ZKHx8N3ZaCdhJ?hb(g=5(I#`QG!MwNCwD zF|)d>s;l;NSJ%F;y%h#}e@E}w%-5vA!@<2fhxU`ZGm0y1&MnpDi_SJzf!{+<;A)9$$kkJI3yv9)< z>j>_kGVlDE1y5Jkh)nQhbSqT?K5>C);8~Uwf27WFWmoACUJTv503(Fph%gyn39B6Ib1gVJtKRSzA1%auzzhG%bvR<^-y zY(d>KGc%mT#%4ywxxGcIL)J|(KYoP&D2u7BLO5$SKuQ{2Fts`)z)wv@17aY~m~((} zXrc;K=NeoZ=eTd>qkhScGs$!Nowk!p==-P<4YE^(2%tI;oAOSnMweZmdBUoRD=iw= zB>gDsGefOmKtDW#8KT0zw{p{RQ=89nT}9QYaZemGQcQLc+xhg@U=qw zmgtnrv2Z60i;8*d&N+2za#JcOw?}z#=7e`@WlddNS3mlb5r=x&3WAiU`GBTolV;OP zWmGg5pWe#mlNhU_CgwY>(yg>@_28~Xe7XE$O7sNZ>g*lZx;L6q883(8A<8BV) zO{4`@v@zyXsb1~N*d%rj({yyu2={ln%x~!-qWkI8NSw%EPeGV>>ZRp62nZqO=E(yq zmI$rs>4XBbE41l)v~M2Ie0mZYOnDL??|kS~xNf6e#udizZs&g!GX|I0=2lx+o7!pn*vprzzl1PFm=xcD+H`Q@XFS37yvW4bvJ$Cos;Mv5sFe?*r zT67E!)V4yqN#bF$yY}Kz%NcNN3*G_%C5@Gj?WhUtScTmyp8|O(tduP&-7yuVo(nEy1W9(htNDK>1bkp z<5C+D6PF|rYsxQ-FH8s+gmaqkfco&8;}a3M=NglTbpDbWTB z^Ivll>t~fA>;(e?0_g0V?7Ls9h5sYY@D<&ixzCPSRI<|#d%Mx;kls-ga`cngVUmyp zx1~Qz;6Qj0`2z(iY81GzzN7tee3WwN`6d8{2lw6-Lj{jQMi$)NC`^M@0|MmpNd?z#sT@WYQ1pQeHhM z!{Vs$)*Jo?()Lv9R&SW;#Rzt~q@8@_Oo9$9Php}<)kuf@bFaBY`PmBvg0LuHnJBU0 z;CB4JiG2keruJ+wYW?{5_^I}TUH@+h5(F;q{}w>*0`%m+W&1S}B>Kgl8@MX)#DY;V z1^`3Mx~JMh2mSL)#qth)@~N@kR;&RvLJ=BO743q68W0d%}*5VBk!AaQS+o40VT`5@r1J%Ep7AWGO0oC{?@+ z2?+^D8jzO@@Vk{26cn_yw7dbD-&xEDKG)YL4(`ZOW0$Fq9Nc((G*DA}r^)fJE=GNQ zeIX$sfM@^!341=+ALQ{eY}>CGA@Z~+!D8^DK+x2j$xw2D@L<3}<_9i%fE9?}s?3=5 zpUAc?dg!1yxuOmh`Z9G!OeAF-4aTGntA7LHOVC!L&e+!4TByo^9{LUm-jsvjc_wcf zioDH&gG_;xuS~DUq6J_WK>I*1;db!El$4YJCPQC;eF}iMG?Elc)PPEpy>FF83e|H58&g8*^C(FNHBS@+s1pt7|&K1C_fPhQ|QNZM0 zRrr(p?Gjs~?so3>diK%sCbke2d=3hfB{L)6SJoz)oD?5s7f}u;~&P z`o9C-BL$dpXxn|2x4Vpzr|snsGX~~l1wd0;^c4T$7=kZ&Z{6@iRB&E`1&#jo4HN#Z zSn@=n^bM$M+x|aR^SAM+(F+=asTCA+_(kZ zhJ*RErn;=Y`el0lWtFn1u%xlGv!%1DqpC=h9#01PfdywLrO}f^MM+KC$tlC1^|ey? zQczb=*8{DR-g-uHl{mSC@ES(K=NVFK+ta%wr znoHP+jxu(36m?WZKP+-1?kpDV-K;|J3N%@>_SvS!Tn{hf--Tc_H4$*lc|5I+{}{a3 z)w+81(>hNGX&ZE7b#1KWsBg$>=h!{H!MMYQy>33f=>3e92qD6r=L%KOcX>X_0I!fv z&jF$Ngp?D*D<(ekkv5Gk4q9w(BT7>K!u{`1hMSADY3nYAzPT`LG;J5CD(T>W?B506 z95A8td6z^yteT@Lpp>-K_wsmD>9ZwI&u+|YjLnmY7|rf8qwFgM2o!$FV)hb6e)(18MuWWPEuYf62Q8hHoxd%0n@g|MpEE17PxAXEZugwq9#wu`77B2bBl4>0=XP?u8`@uwA zRKspmKnTm7(M|ia&kLMpRLvISE3_1|=l-_OODpCqUBskyhx{NoBd|(%jDhK8ZDomi zD|{8l@8$ebaPw@l!Dtj2O!ufUvrrrnV-8b&#QM;K74||xXR~@%@3hmS9XJLek92?+ zzk~Yy3cvPKw|DeM^EU!)oMh($k1$(tn#V1j&+9xv@44*h9uDE}MJxmJq>sn;u5c{c3E&+k!}r`; z>$pwueB~v&o%0=X|LOj6JABhjN<#;hANGJU2y$}n%tIFYA3a(mANk4Zg$s-5z`tD} zf1)dRFGPH@Uh>*MBNz5W;JHmANQHz-XGQp3UOq;ausfuj7g2W%F?bl>s*Q&sg0|ku zlia{?^0riGi+ra~ku7pWTvn)a1J7b$98AY^mXYkdm-Ijs6QH zW+Ex7r(}H@ZcJpSSZ(&OzPVg`=lORm>!4*G{CzmPX#_8pRIk(dd^&OWrxyQ(p^#Tv zwl{P*vEkVmfaL?yBkK)?TS)y5hASaQ43lIQox|Qq*=g65+*Cm7asF-1p4p#TWEHJm zSzm>U$P!~okev)0hv~R(CjwJ)eB1CFPHnEIQ@6g_*|AQp8%bAnjxj+ZNhKAwBO!R= zZq~XTo;yvIouLzhBCMsjzN>+MTzup@-JoN`C@B*g3Zn`T<#|E({6hv`_Xq1ZAhz!2 zf{;qB+dHRYLEl9NY?mZ&`N%81Mz6)~M6HWXS#W%syWsh8npW(&A5+yt#s15*#L{EiH7pwM=tlq5Wk8<>0p` z?Lp(S{K(Iu^-gOXe9>gCw)J~DYg53AaCQj)tZ~1d)gQ6zdZX> z)6z;8>+RW&f)oldzGU3~JVL)o4=!4IEqVt?gtzl*4@f(ix|sT_;j^Pk%JBIFCJb7P zj@TgGdK%?tHCQN`ELq&X^Ak5@;ML7@mm!4s&lnWt0wJGxRvwa4+4Iv>XrWvP> z(2O>}(<{L=$vZ!<8kN_h+0nLx7%~CJNBzn==wFS&34>0|4xgtQQ6@d!VB|~pr<`+^ zVNZ8jCh}8boyM^x+r9j<)kP*U>-?GZ5lBW!iVMRo$ETUEiQLZWMy?7DNfI+JPgjqX z70Ks7+yke-_Ze%B+lIsiG%o|e`gtcWJl3m+M?3Ec9k*w0BAPBvZIw*=>*<;mGx@zC z`vr7q+DEMQjOBjyhFO)87}a`$PN#n>Lop0YaoeAim9-4_XJ=T$lZ<_R$B*;-D=Z<&t}>0lIojI zE6aat!R^-*)vH5WV_!I~uVXr!`ntSh`13g{srDb;A7^Mv><)Yi0(Fob9X~Ky30fT^ ze@3wsPVzpmtYY_*H{M=s>TR{iP2Y77w@WRJO7e-L_ITjiQ+Y}{H{ ziz?K`vMNzbWwXqT-YIN+4Ha=_a2ZEL#W!WLl*8C;H|`5!cRFC&^xZP{O_b@*yV23v zpzi$bb)jkQ`Mm%;ucCa&v(Iiehej{PFZ-#yIDco-uA2S8M^;54G=MH{WM%Zj$h81i zzrtqGZ)qx?7z8qyQe}>Ff~>5B+>TaAeQ}6Fj7e=j`dhDBm)wewqLD>HcGU7M^QKfg zqt_t$4hU6ZNjrC*9>nRTHJ-sYv1|?m7wgXBO%T??@)sZgv=#yinmG^G$FDXOxKU)h zuKNSIaMf}rOX;nAQ#ZnAiiOYxf?2)&nA(gE_p6@opT+O96-Sw0^b(Tn_b-dNKNQDg zvAHEJZul4({m^~6moNmU-Iks1toETycaIJTpcA#wvpq@OUtBbQV7>ctiR|MQN)Xv` zzOPj~-(aM7k|@4CDy^-1?-m}_wg^l;$jI@FJG}_iwsoKFMRcOYxX#BFmx-vy`X)Q% zur^3}&ArofD6d5Uta%IHa*X|@pi9ePv+=;9g>b9K-QihZUpg-AphV8+xQCy`g=;>J zH{VApQn)J>`~(Q|aZI)5U3q}5U@_t9Q?sUBw~W$zA}@~fF^cAJYLIXVNsNG#aM686 z>;3iZuWnE0n4=*NUyRLWS^D%9JsIWaHM_ISye8ZNEeJKPtIzsxe(2u(;MGHd!M-yr z8cA|IkYZu$tVnHfa;+sRYm*w9FBFtC?8Wo@ewNE%zaDDl5t&dB?Yz4w+~o9X3VCh1 zdB)hZ9@rOu7R!AOX@8zP%Mw~w{Vr|w`ED@Q#!wUMEvm1_`A#8Gt*?O<@b1SuXZzH! z9GSut5!R8Aq^B=E>~Z8322r+eydH85dgNK0qlzevTm?<4NM7e6OQjHql*rJ01GyEft{7ZcE<@$>N; zg!EJey^|~Q+Q#TlGk?VDo+d+IG|@Slf!}a{nzUqxE=QwF?s@iYkd+tg;v^9}V2aEe zUaSk=4#k{5QWrIxM7A3?pF9!)BvyD(X#X{`(*=i6eNhd1exKyTo{_@hoW1Tp*Fx)FeP)=s!D^R@-%Oxeh6zd_Xn@9PhRK?xIO=^)qOC`M*m_P zJvT^ppC#yHK6j_i4syRU`r!SL4R&Gm9K?2l2Wg9+ul5{EwFCZc%x{h@@0%`xS;CKZIX%H~>rS4DHoBjiT1N>TyJ^$G1 zA}=}HxwGkR`ZnR8wYI_g-;Y7&u5cj#m!5H>JYk|iAg5r^^OFvNTiMA#-omd=P1#k4 z-NGYI1S?&u>BE(#;wGnL)=Z(k9`C~?f>C|EF&9;>qi1ExS$NMZ0IroUZet**^VCc zvpe1Il`&S;o-g;?XOplixsRfV`Np>E3Y|HrE<2uUD=K5f0l&h~1lM0;yx;St-*dX1 zN1~vt+U9+Vb6WsR$AL^7{Q5N1kTef$bLvL~oCo)KC5D%!zhl z{xGk^P#hMt2Z_dq8$>;m=@=)rI z)^!GiN7F5})!gF{*KScoGm}=hr$Df+?V{5c@^tj_17_n!22iK`eg1l2yeRpDjx70) zlvGa3^YKP-X$K6JgO;%Q<`VxZ5A2=m=cL3c=fWNw-T_o z^XV$`zbq4Af_$D1XZ`S6{%1s9uY=mG=F#ddo_wdN(&xi zj0(FX>czz=G}H$Vb3Sdn*xgqQx4BK(jE?1+@ZOZW@LsfK-#jVmSxe;l_2nflDrPS2 zSr+~M>1i~6t9{d9=K?&R%ub(^^4eUz#t5t@G(isC6>FZaDb5Hr$6NgwKKBUcX*;Q?p%h9FHavyOD2NJZVA82L4GFr-aMz#mA&6t2>Lk2I5gDhF>Fyr7;Rf> zX`b5;52BW?TsraE((n};w4FUVB)M7mb#*P`4SfpkPZqHJ6VVzG^X&R70N4!Zd0Au; zL{ciE2$)E34^VRX2#U$&QRNM+m){fW9 z-M(y>f+*AGUOaRnc9;7nh1$vE%;r!q!}INv!k&O{UCTA?I$K%*^d0khdhEybjxF9MWeMswW*~c-BPM5@q+%(xa<0 zu8TRw(3JzfmYS<97gq9QrWz6b)lr<}W2!0F(85Go_kvc#XLrN7yyYJE&uDy)hD@lPYw6(?1CbTaN`^6b{)+a(32=9J;MSYGBY| zKwCzftAIlW)uqn7r)GU_*~FaHvGHti(Qn2jv&s7IdKu*iw6&66!ARKo{aCFoyM)f? z6y}pj_e@c}1?rOkNo=V6uJzM6dT#cjLZ)5K)aD#1?{HBL-4hS&+&tx5BR|FH3|GeHRMH zh46R*ZmtuFv8R~{R}X>*VPZKL`;IT}DO$Pl=F&$**phxRhxh+AX@y>f(M0sC8uqI` z3$=~i>lvR8?Y<82`-FB9=REo!?56$XO*wWyxfOz-c!Q9b8tsWrr#B@>S#qV$P~o% z*m6wnTQZY1`g1ftQ4Rt<4z97}#eE*kQ>P4=dfi_x%qRUhd4V|$nj+@2H{T^7!y9Dv zLGowPsrNiv`%Z;6r25@LR(2h)2u*HwgD$fz^S(Uo7q_|DZ@;;Lx0|H1uE*uGbm&hk z&ae@aZjD{x*Uq|(ke;HKVY&xW3(nV zEe#6*e2EcQT0UDif=a2E*zhfbig+<5^*S{f1hbzrnA%r)&8a@;xW}sz4)|p zH2i9+Z0Y#S)E!xLr|PS8x7jIJ2CHNYJV5Z`xfT|{3JQF##{+kz@3hD|+*xPszmPRR zXLjaJ5f9v|v$~&Md9~ea3}%Lrz&07U(WLC2Gd)EWDb?CU_^zjG^(8dp#C5G@!L$#n zNPbN_L$Xf#p~td;JLCuI2CeOGV1XfwMZC_~KEZOXqSyeqLEsUT2xUsHx+3 z`H1JXqn3pB>vU2X`jXPpKVN%z_d>1-Ek{QM{;tb`WF&9{?=yD4{rclF;!l`3LMzKb zmKDCy=r9rW{f0Iwht1|sM3QbVYiFqhH&+Xxi3PtSmdd6&hl7=axW0)?1u;1zJkK4Z zJ91*6r;4y871(T@=B6*a*bkR;L>B&B2qOP^9 z!8QP*{ZFBdUTzNmJdT}YImP%Q?A22`tY!h=5lx<>3unH*+bJkS66J)}-0w+79u%Pi zEVZ9l5I-p<+_pdJJ*>BqW~-M=il$0A8(8fJo1I(HDQ59lM2!9}W4YO9dJwP=9y4NV zv2=A^K+VLblV)?e`i$g?M2;B*i}MM1gGTi+M42xCQ}<`&UNOMm|Dd#-9_$$d;BYfp zFD=+M@l?)XsGLU<~mQ%&-*|YiL5*2Zl;Jt8KRk8ss8WY(EixgX`__l0ON!{{F8Enz+Rwn^kIBPyrU{jB~%M zp~k;=PQ+YRIRimwQ#;rcu!|n2`9jUv-p76WEx<;4&x;|90)nVIO?*|A7|uylSvO)u zh+1cz!Xr6PbhS%yz@GNb+hKW9aCEkpf_I$?PLKClgNh-<{4N5XgZm0rQW%`OJaW2L z<*R0!qk5rlXWNB%D$~EBx##2<^0`(7VfZs0SSI8aPndTPu+J{))O4<9kE^OtZH04% zqiSvyvR&(Q)Bce~&V()LE<$y6aV z%kppIWWA_CxuE>GPNG%v@)|zJU}ADU*p%^kvlqmk;8JSruONTeq(9+)Y=0(4eP6eZ zh=51N)I1uAzKs_iFZg4dK+^Y|+ncp;Ouh5ncuxdtm$4->TI!TBu(%Bs<(a_et ze?Gskp~55&|Ap_${RE$$S3BW`ERna%o5V%${;{s=?zV`+>s~|{7YhgLxMkTZ>!4{z zn$--q(Y0~@<41?DFYvlNZ#eP5QjwxCay0RB8ghF`@znj@<(s-h8cpduZzy}1GWDpt zL~rfR;Nlg7kg)SV4FpnP`zr@M=45Au%_Jd3q)@QIh$>&ZWsN02yzwAI`G8`?NKKW0 zcJWT>!r-^{a(h|gf!&?oEp=rStMnmpNKne_t#MaVbbWE<6{<+WYt^pO#6W(0IEV(* zl#Tin+hxaL(+r1v7C*ukODUqK23Cp2PvbC59bvnVuePp0nwA_okr=Q;4nmM?K=UW% zH>8$?cs5v5!XzQ%h<(cKRZSp;v}HL1K`OM>gHXS|DWvY&Od(QH3sx}2{1Ffq=-`eI z9pnv4J2O}QA*<{>1Tt$H(&WnEy$=XLO7cZBr+E)hc{154d0;p1hk z(-+(Vr0x0yz@>+WUGEDNDnxwTuj#j^J1kl%*Hy#vMqlbEGz^mp#Dm%-*8%WJl_uEM za=~!k`0^5Khc1T1(!|{8YksxV8zfW^D$?fuWvMTC)2iPycIl_%%vhY@SwQkbEJlnm z56Ll*fFo-7px%X-mF!x11!reIdQg7VQ;a$85A-NhCYwPe zM?!&-;pKr99mCiHWK1L(a2h(|GyxZ3%rE#)Wy&%QsGV&{ok+Cw@Q(bjAY@SaRhD&< ztJ`H;Ff94mPgwRVk;g)mM8$y*KLJz*FFY>~pgRjItJ`^7TXOu+LCQo8J-wUbO%D-C zHWmd!6Bb;cF5-sAxt+xA#M55`QTX|lMj+5QX4225E6|||_K@D$1##)e-~`s)z;p97 z`R*qJ>@DZ$%3n)NAj>){$y_>WP~L?ie$I=R;d&b_lw`tYd=VGUP#(+GGg{emO0l4YV?!{%9b8K1s1nE%3fN@~Ml`h4;&mSDqc({-w~4 z{@ut`cIjk5rL5}DIC?qgDw7cjCkCRfL5=6c7wJejZyLy`{lRY3MhZmcNS%16g%C>C z_EMZ%&u%x#MI@zkmlYUKQHxjm6#dUHY8cO|?H0*l*D)&Zk&=~oeY;RUHy1Q^ZBTuJ zSHf$yQfITB=jD^Ka(8^tQ$m(5pyL7N=SHeuWO=yUU|)z*OY`>bm1xW3Y#uC0b`BHu zahN!P3^p@meKZ>j@{6&z7I zO%B4ru?s6|+hJEHGl-Vp-_B{_;(%NI zu6{q{GtknSW4i03RKT$YJ_uRyc zUrQ+lq&Z7i!*F9U@KITL;_gJ6F)FX!Qw3Rybnw-FxEB)*Evzfn-r!ZYt2tTvksCdM z3p8_X(R@>1jj+maVy#gTyXRO2jOf7nRul&LoHVo%Z@*;tZcHJvccLLF-GFThq9p`z`T;m-frMf?*b&SAgjq#qY zxs{$ChtkCH%k7=eRqa%wZ-<9lKT6A6slj;#OyKe&{qBZ(M2Y z3vDqSDFasmklDCLuof$|57D(09(~)?M3ZG%JI#lK{>UA-Yp;|F^o*K`52oX54j?YG zoO=SH(H)iWx`*fllpBoGrQhFTCKJ~X%%S1u8?T>3y{DJ;goF}}CSq_wVaJ9f+U?&4 z3sgy!a;?iJ6kA*U`mgU|IZoU`{>3Xzyk)$Gcs_S({!i_Kymojgu7GWel$g^9`9f+Z zaeRpSslSyeM6aF@U<#PYfUj(uH(c+u`=8f(2C7{7QJsHfkw8|BHHiOd4Z)Ork{0^+ z+vHGjNGzECn|fVXM99D|i-VXm5kkj9SCxv}RgeVQ0l#fF45X>L;nd>mj8dR1^=NLD z-A9=Lr-ieY*ISicmWSn?=nTUFh;=5vQ_s*|g;26BhSybXVkvKr%T@dLM5)A8#_XI( zoyKXp{l7bZG;wMge{mgM-@6T8TpxcJsn1?hgevEAE{)9eWOfx^)|2I|wQ%$CU2FRS z`P!^^j<;JZ>K|I;HCq*0VySqUNYD9v?~~8)66}Hu6f;9D@d4 z#-x{)*ks-_NK<;d{klhs@i8!%W`w2{q+0TMyc92Ol`2F^SImK9(7tfl9WRxAUW1$L zSaeJ6gbppkscgK1oHYBnH?Q0Q1ULCu<6@wak|lPC7`sx3+%J zX`Noq1}RO+fR@wT@K%zsJC008x}6lZHks(t#*!LU{2)m8`>2p(pdY?YblCjxT#uTZ zUi-M!-5S=;_9A-vT0l3s`QcelP3Q8yXSraJw9pqjpSU=t45qo@^lon_w8u4PmkpsHEfm9v0E?s5rriK>v3!+;pIuC@cUpd9iR$sH|(im@%((JV! zn{Oeu9Utv0Q1SIu;YA4sXd0eOd`z#az2LC3dTFkXj^=r@sXp1+eU>bdNweAEl4@Dk zDk8Yp4nN}Y6{-jJq_#|g)13T|&*wt`Y-;%l zpUVPa_114)CDrW04)=KXv*)rcn;Y}!dR6f)GHPavEv}22S*4ko?9DJI-H#JGXM=hy zj0oax@MNt?x92XJe;&mLg*q16yb!Y@BEb-jyNO4kQE9Y!<3BQtmV|+!%nz}ho)B$= z{)2?51G=8Tg-Oz?BE^B7!}R1pVhbD8nAX1^_sp&i>Xce8s&a&DTsGW=T1ywJ#W;!1 zTOM|I<{Fv_V$b!2Tis$;M_N#bZ4m5z@1K(}^Lg!;3YTpmu>%H5zNzWYwA)vKx>^&Y zVe4%k>oei+NSKa}E&bw}N*z&y;y`H_mNIv6;ZX;zm^_p{0yw z`JGnt4hGvUJnZ~}H}gfmf2%>f@83Xx-gJW=31PeN*?J*U!9k~57ulO41O(@M+xt65 zB(6uEVn)+971Cl-I`-@tS16w}*=yah>lS!#$BI@TY&&GUuXZ&o|MdS}%F@-0CK2}U z?NVD3a5cg62$j_LvlqErulQMLp_H91g4yEn+84hvmc0SPqY=q|B9_0Cs46GYDd%JV za(U0)Yg4)OS0s%sOghnpRRkjEOiknR6SRW$a3i^B$-ka{womAt%CKFQZ^yXlkGU=E2%tJs6o$DI? z#^}juUbXt3z-4b>9dWoiApx6gy$##T{ozT{WSl>@`IyT3CwmpVv8-gvCrxI{?MI`@o`{BEpA+AK7n3}qXboSo?byRR zGE!nZ=ts!xNprO=X)O9%w2j}cx?9t|4xv;$Hm;FTotV%|+v`e{+Pn3?> zu7{O3dSBM(&P4Yk^|-`Z0nOq6++HGKDdd}4D?2JHdoPXP#^vSZ$Dc4r`T8cNzaM`3 zfWm_KkjO#P{iLU_&q<{q@b0m9SiGh<{BGziRk4CDm(9vjZ9!;SEqHh~y5NpzmutqO zk6iHc2XVDo-~D1-P4oR?P0wOWPs>(>fqQgxo_lewhB-7YuEw!(#AVb*5{@N#L&z$< zYDC1oKTNN*LI%IdN<$gd86uI@D_18WZQWc$<>@JjbPUni$0=3m$Z^$KE_Q+~Hp{iY z>?{Q&BwX{Qec)0)E*FzThaI{xJvO_Z)LNbeF!x()eNKzP_+BZ&rCZ)7gJ#|iJ}fTB zebbAj4EGG}&&_YfdGnxEb=X74D-(*np|K} zE$eZkM2Z$`1|qBqM7g>iT9`j^52TOG%}wz(kS=Xb41BNY*a4}z=--i<*t|`D(sV7L zRZQplJ`?qQCuDgw)uHokQYb!Zfv=*g37xmqq0 zLR~GT&*HOF6DyuUqY{GBUd)6qZ5B$Z(^K3e{EoXn32yc$h^;J4Y{#A+QQ=`VDsyha z!qsS_YmV%GRaR8=>{$|`*E!(}`QE11s?kN0>>uuO^{w67nY9FJKOtzsNhvsGvHMJn zO$UzqdT}xC2Zo>#9PwG#RHor31=0C=Rl29QUV#Qx-VG|G3tLR{9f$^MH;|R^E6<}< zBBGJ8JNzkh*eRKGBHxM7jxMnXch~|=%L)#Y&GSCqB$t}1E zt1SpYGN0?whigd04XXk~4}mr6uF1t8?ubstti$o-D5OCl!f-Pmb}U`z&I z6?BV2{e4wPc}&6C5c>|v_}$(7+!s9)6UYyffi^{ao|$3g=+e>6}Jk(PiWE(9$TKK!?vliB&lmD_dbn z01NSd3V;;65-Im!t}TDj*P89?EyGA_;MzZ|Y$kIeHCz)>&xuMx|KG=cP!|NTt&Vw* zd~8l!WT6xB#dhN}p6_9BMR5N0?Z0HgKUm_2#>f9FGnW?ubf^DQ{?ilRKh+YJP;+ z!4FAt@S>eIlmB|)Ytx1(8mG?K9|WoP7t8Y}mtjc(a08IPYFS@7A3zmUBSz%YM~v(_ zek5g$mqCIL_`)=>a|P5Wsq)MFUj;%1h@iO9y$;PPt*!WB)7mdlfVQ0tkokug1&d8@ zY-|8X0DxHiNAPbo4SWEyLI8i~=jYegnUmy##qt3D;_&dBmDS1dvE{dKU2<=Mern}w zO*b|IugOCHAs@(*DC1>-i$)Zuj0e(4NKhV~rM(RnD^g`h9NzsWyayx86{*tWiTwWt*vN@4aTusyo$(9}{pYYL z__CD!pOt|=0Y?#jqKyA*HQ5ivD++u*_Uk$3{nrvQylBT!Jvq|x{0Sd1`hP43%mdAC z`0@Y8I$V92hH%r-#O15vNG6qHLySalB>UyqL7y0*80PTzwoIB4wGp?IKIf`?c1px= zmIf*RnJiGQHet#og5@Z{S(7K*SLyEUilo(W!0DvbfrBTzcU*Uup6&^*;hz{jB^??r z(ELy(|DFPTC8QwqMgJ-EwN;=MUO!-ez+AKf2nDLZglV!u@?Rr|X50=$A)ATC%gkxd zE>m4>-~3e##(AHw8m~^9U?g%%_g?M??4^fyXV|93EDdg?mj&`G4i+PJb3~g?E0Dqk zoPmM!iLsAyM&ynTZ>T7)L3d_-c4KySWtQ>V8!_?=qSW55{{ssRKux3tqhLWeBoU-4 z7-{kVV&Y6lqSW0Bj}I{dSBqdL!HZ&MDTLa`#nJ7eJo>2@{6+JoU<}&D)DK3736r2P zDtefF5rq#^ET%#dqnh1y=MPu1+-v>=La)#KFAMV55Cj~_1S8=ueJPigAVVofjoku! zQ)=WLD#6mdb4mZ{in?8oi7pqO=C7f@CKdR^lAt&b{%=(3|3gascW!~%1;e6u%ND7EKoR%8hz5*Flzi6bTVPoD zhw90WK_`!HCUE>>Z~ZL9I_ZA_4Fg-XYdJNJ)@Ot?F~k|ZcFx&B50 z*plIV$bq5-(}(}66{pAHLH>z@OdSuhc7^$$4$#4(fcR1K=;I{^-lY;#!c3ZT(&OL; ziy74~OTfl=Q?to1efkMx-=X-#1WS#5ct>IUOp5acG_;3Ih=!eqlr=^ke`Jjv+-F{= zO^h1}H1Y_AzqCbYq7CX%^Q!|EF$kC|Ls}_ZA zuJz(QIJ<>WV@l+y8HGvg)Gcw*z86)NdGtDpd5wWyModBL39lEue89}`Af~u{V(dV% z;+mm|<3H`ceioJ}iwXCFZ%WECkp>)GozlD z&4{|rE7|8^am0rlu(x2xZ_!8SaeGmjtcpQo$ZAYOJy9*kt+yw4GASf3 z34uY&o0%tIM8cxiITkT5-so`W;~+ObIG-AVYcobaLqQk9e@EcN^16MK((?YU()ec& zxl>rVBXT(<9R)Q3Dis@QFIzwtCcJnYd;mETEfohoZ4Vn(h#6ZHITEZW8~m`!PYLQ_ zNlO1-7|>VzfgMcvQ0XB)LIOkz3CaM>OE!48sgrvS8bs~g@6rp+X#7vsN%=qb{HSAm&=n?XH#R_>f(BNNftn*x zcCh;s!#4)+`@@xGal{uYR}Y)bCYuwU>fEjRgL6|KrT{*9%9O62`nLBRna?>{?nJQE z4AgO9rfeAl#*XSOfE4OVkWsk9)8%5NWvHf92;wSzjuHD2lN5{O9dRAxllAGNQ}c|$ zJ}#F_0cQ3HC2SB#99t$pZELRv9zzWaK9uf{gCRL361vh4qql&h9|Q|S{sR;&9|DH! z?u~;V=w(Ay!-S{7c5tV}3MJ?J_$Gj6>j9Y{00cq?M$`zt+s8?mGR9w={0l7TeD&Zt zk#JtO0`p^(R<5ysf)R3-B4r-4z6+VbMx?h46st6>uGJfGO{|bTiUNR*_&y}#!9KTl7KFvZ|G!XyVGnxHU8|W z)7g&guy;XmTHW5Ei^3N)U7C7rl|t=-{-sejj>Q734CGQH zFLw@(F|XNjZc&vK(p^nB?4)jG8t29R;z7iVD?_mB@bP;qUU)Kj_uD*z*qUKN9PR{! zc)7)G`!CkGk-bJ7Wn6^WpU8)j+=-(c8~EfAJ_mQ3TiL6B!9mXG&fSp(B@aDf6TnFM z6UXrr^F&XWJ1!BUCwHOLMe!D_B&ch` zV`0nsKeY{2H8> z=R^zRoBQv)pRUhlB1kC$3%YZic~ih1j@y@4hs?Gg%qI!%91EU ziGyUahdq^%i#EJ>`YRi7V&u4r5vL3nZDJJcTWT1P7>M$Hqywe_jHthaTEXxP`OE5%7a*K ztd8S`z7-6ze!1AIU2%y}^Fzzbt!QlOtZDcq-W`a+O2VYCy1HP~m{XnL?34|$##*H+l+PSsf=2+ERk zNtIH4y4f)?uR@YE*R-#df}?(|JB{uS3vyrIE6T|zw<_25O4rS3(^(Y^%98tmP5++K z*G)k~QvbW8jfoRo?BdMIzyY_btBaiHSESG_8E4$YZdJ8Bu}@Ops+lV%d|oK|Y4+yp zd6$vul=W3naWvt! z6WoFmT!RM-?(Xg`0fM_jaCdiix8OQx@Zd7R-3E7uJO8=so|oGXvwBw7s_v@ls_IYn z-a1NpQZiGkAp8rV{e7*aW`q<#62`JV<7ZyEz)?rc4)G|{8CrJE>?&CmGFd|xF`cV& z4=V_?$$_=;CVFB*Z#6}hNVL@2y0UT`P=oExzL0{8qoKL9$i>MK^>lV;M{JPmNpAor zJ^;QRIIZz`A{F#ws;#Iw!ia=HPzxO_Nvc#&6c3;cOcJJK%VZ}=k4Z;Zwf;tr_EA3}Jw5m3`-z&2uSBS_c*qf@ z#ur>NS`yJv)`)-t$|7D3iBQQvfO0cPD;2kA;@2C~iJhkVQh9e$RGMT@f_N#0Hal-r zunJ621WRnukY=IsCwkmwE{znQzkY8_j1WNO&`Z%c*uDq7NbMgbYY=S;3MK$B%}K&x zyjAh3_3iIs3&%oBtQ*Hsm3RP6aw-7Op&zq#C0yCplO6)uBgkOqc&IIr|PAb3jwF+$HaASPTMsWixr|aff3dD zYe?unz|Y6)8}EVRLMc3tTLnP*XII1d6U;enpz?x7B0%6_ZxnI?=HYdfu~C>h zo_{HRkUG1(yS-i6Zko5)9GmCbO`fPC_{pxl@%Xg8h^OQq-v_AA_3L^S4K^{EGKg22 zv`KPqKB{v4k_eajr3dK0W4SQ3-v0tkF`d`p__Pwa`|{@T^sB4h5XiXqH&zN3C)YsK z&tmgPq!x zqDJ#iu;r4b)nFS->qcd|zYYwHqtX$vNbAQyJ7Cwt6j^=1XvABW57755$o)JL=z3=- zfG7Jc+C$ZrMy?o4`gzq6ghOgnGZ;kFtnJx@(XuwzLZyRQm z`q9yMHwG77F5#dr7r!e;gA?Hgf`fuy*ZE%spxtxZJughZ#|!_QS)i45nh*9)H+hf{ ze|!r469W4LOUmQ)JbrwW&YaKdbrdiiSGyq?NTRpo)n4oLfP~271O8>Ai=`w}_WcKv zNbrElytx`(L2Wnp&1`9Lmj~SW{l)>JXHyHOD3QE10vEtTsJb;LHTd` z9*Wn4U0QXU@^nvcOd6!5UJehsFSAcs-y>OktwnZp#C>78A) zQ&d4O=Gyn{9#N&^-F17poN(q90-|h#VqS9*OJTt9wpzzLUW>B^ z8ZRJ0j+w2E6`NyJF5?kHyZc@9N7`q(!}{o+)LBLLoCeR-Hvhf@2~*cA3B>d`2VHKn zMR4vkL2rc9&|&yUFo-FuaqQcp7YD1`N$Z4G9jOp5>qWz1oSHaIvEVMzmKON#gD~K1#eM`B)OBH^h;_WF9|6a zhCEJHjip}~`Wg9~t+^Y4U5WyAdvwjUFG@t)mJW4v_LWnfDURFY`yqVk_8Xmq-kgGr z@fL!At)Bnj^J14YTrP&+N?DNVuVb}8tWE9>GXWgMsd0j`30X<>dGNr5tuzOJfEM>ahrG2wRBMn@l^ljZPS4x_cX<6ghK1T?rA^vcjd)_?JLA2K~>s^02|1d z55){6sp%oEaRr{hU^PtkTMm5oUs_u6-3^6J#kGYU?VWYS1_2%!9nLPJ_S0@Q`jUG1 ztm;lI06-t{z~7YW@UK9z;<%0W>|2#l5?tkNdPp7|G`7*r9?E0-AZxmWI9tp05h<52CJ3R+nlxNucKaT{exr5tdSa0 z^(^ui9tFIiM6R?$N}*1d54S~+x`VX%hiM5Zh=yZfc1aV@^VMKU)5$>$*Z0NwmJ9-y zm*ZqYnqY|DWqLb7Z^Y$Va3 z$hX!fBBTx0!Py1ZgjhJO(8>3rl?kjVNy&2|e>sF^8au)Fj-&qb$z;jp6`j@PfARWm z_ae``C*I}S4RUOX;ZJA$zP;TZ%zQ7Aaz6K`>pjjPyZ}IJKG06@U!_1`HttlukQrFM zzT$=sQ7ib10;JOt?q1)EYkHDfT0Po0)wx`Se~KxvMPm%s0ssu>eZ(}$tGZw$Hj)wB zTszYsEfYA1(YlEeR3KUyGpvl%^+Aza0^)d|I#DH8Q$XQRs_8iEX9yq>=y@ z2^i=#@$7~SVpt|3@V(vv{;4^=h9Ggowe_a0A8)DnTJ5iOn@y^cOU?XkD1yhy=OV4; z5dZ^Qa9Q+O z;zXbs_XdmG{cjJ<`Fx!oBf~tVwTv8OAysB9W@m;D9uIfBjBa=06jafO*~>AT=#G^1 za}I-5XM%nh@DM$>43@ctKk8+cW7D#9J`c|dX1D+VyPr?~?UACc$dW}vTF+b35aHK* zsSf76jm>fU^Jii`b49}K8VdmVa{fksJfG{nA_c(HZK5GN2rb+$gUxB$H z)1b=dq5H#P+%9fg0YG?mu1)~Dx;ps=N&5~=BP{)rv1C2xE- ztJ6W!o&Afu-DbD@;&tEU(c1F7Yu;m2n* zi}IrxUJ6Du2t^Z91s183Qk5V!PWciWvP;k4sbdGF(4x03LKvwz7c>_*k$-iru1G)u zRQ{Q!b(|pxbnyM*;&wgE>nqq&hz{rBj`c7&WSz50iY=`zZEdAr)1FUwBJV091_WgA z#cb}8wped0h&+SMtxAc1+! z1bpAS9>xx*4P__kZIZsLGvpp9XdeI_4w2GTb`8oM?pIqam#?jMbHn-C8FKmj!H!=k z0E-vN@wpu-DJip~Uz=VCr}G-!U#4cvn7$6jl9r1kXF|Vrgyu($rRvwUm8!b?R#aFFY9FsEDk}~u4FUO}xU-+--v{OW z9)7F%?)F3HO5v$gCR8*uem|@h(!bq4E{4xML+Z{djJ-KBUdr11t0x+2roc)RTdE+@ z?i%zZbraM8a?I*wa(u~x)hy{er14!KFM3XJI%zxS{`N`zA&dt6MMMy2Aoo-HtfaA)yOWihw^%$j z%>ibXi6!g53v5S7|=)#qOt%;m`$C8u1A4W)GVi3@7mwn#%y*~{USXDx3q}g$b3N(~w zAW7Cy*GlPg!xf@!f$eSJ?-I4_~OQdc(hMRb!n(jd83-3q6F{qjG{BU zSRV=z;j&LXm^9=^Cxp?34x;#r4DjI0Tdl9?d)N0&g$Nj!Dsw_Y$q`ThX9p;G03cx& zT^b;VE{s09$3T~erW`PW5lKlwkv>L71QiL8O`1qShmqsWCKDc>mqDR6h?T^SkjBiB zmMN+@(NoOiFkQ}hQasQ#AWfzy9vtupgM+aX%Dt?^3a5?0=1;6E5-qKEHk<2_1nwJ1 znrcb8;P$q(>aG+wyS6s4Xq+YaTCqgRH%Ql=Vr)?+E}j_ z9bW=*ma1|GO>3~Ke+sCn$^^5!Z1n%DF2`aD^I~XN*n*nTP*ybrQCLD_v$2pj8v}*z*+0%Mb4cl>t_iJD(?5pLDCAo8vGS8RoEE$6T2Khi6H&sH62G4 z4ly;VGa>Grvq7Dj`or^wG+oM=muQ20fYz4rjzemoyhTOzoN)%qOr0W~(XAavpt6+` zT77jQbHGnwxWvey`VF+f{&NhFAWlz@2e0F>IC2HczWV8VYF#V3q0JHNgB)Flb^*$N zVN$?osw}@K)$EmLW<@oyr@64Pu(49F%9`WXy=>d>f5kMxZ4RsF7p=o~L*pH4OUmPDp8=ric&f@i&3yNJuGw?E) zrGkg~*C(7`ESv5YX%+zmCEJifiHp$rNNi+FMUp6nL>>@|$*=QwFc~31K5`Jt(YchU z0LEA=9xp)|p^t*3SBmMNjoqyoY2P`*gw?Wr!kUyzs2AXHAz@=6sWT7J-&02fAS$I4 ziu0DhI7>%L^Ln*(_qZC-Ca7LIr$C`cR6#poi0&WWerx<5%u%BpNJ^1W7;(^ zIGkDo6B2lHY@fZ1+gAlevszYRM`lRFp`*)@;RUMTXD+OoL7^~32W&;i=Adk0NYkYv z!-xuAMAyK}5`Ch=bSxr)L8nrs%Y@nkey);7L`)GTPb$KURHYAuVHxjBHl_j~rTjGm z6X@XU9%WTl`*h6aF_EB!k;78pev7~)I|iqTu+*1kYHez-_lYek5J@T-?RT&(fWA4t zRgKl%e_?=7*gvidAmmY`L18Ku^(B*0g{a~rU_%wuKWMiZ}=y|_2Vd8iiR@&c0i4(>I$RBRNO8O9*KF^Nd zJ#}@BVq}l&i9^cX-co8!*b8p-j+h4y=6S(1I~dY+=rT^&P_c0@?ld74;wcEB5wwo9 zd9wSKcZ}(-T3a|etC0F(2;x5)s3s$ncjxQUZzO|k4M4Lqq^*wSy zf09NOb4L78T{UZ^jssO${5pBeMt-Aj5ktaZzMD5OEqDz{0ABamV>!gH)`EkBVa{Qb z43|B_XhHBUf#H>bBv_OJS-&KWV^fqWlP7t|QJt}VQhZ&F91XHJYb&YFW=?`>Ze&6;}714lwJ`|!zNt3^ zp%=%%`B~MqUsXm*LqgSgpsD%Ro(I5!EDU4E=%#@hJ!Mv{TtS(}%5`RE@8t9qDF9Rb zp!b*GzO=dSuepia2ddBDx3EsqPVYnTvEv7N{Ca=WB*%6uuc3ul8`PJ6mN;2c=}TD~ zO1ipqDbDxkRA58^qRQoJ0Aa6zrJ$O|yfnxH**A-aV#j-w=ze2U6-^Hgb+zl7?C~z9 zD84^i^?&ROM6YN3Z!T!o8URhkvLe;OmXGc`ANPc1Qg@B9H422uRYyP7h?=`-K+yf# zGJzP8D1E|lzCnnPgcv9SHm1Aei4||8u{qC0nUU|z<2uIjRcwA+u9d`hw){gwp6fJnxx;H)*cSk^ zo?Dx1puO1N_xKQ0BrFTXQh)&o3`0Fem5uKNt>wg==5$Y!ZtRyBPKFFV`)0b0I1p~Xq)sZ%m zQgdGhrW0`D046>XqWHRO0R$#Fvr>~yGoUq{$z!qdC$vY(85{|Lg`B;_8?`%iL<0r0 zDX|KpNMJS8=0)2)#xakMF%!mYp+v&^)KiQ=Yx_G32hqVY0Z1c~eGNt?zUe8#59()|+6<#mKmOBpLcVE~{N;Ue@Tm#I+-wF#G8-J>q zUe~lVc@NTB%LvTD3>_7~=5AU>wte6Gd9+1Q$Rq6y6~7=_g-YOveiu_ryl?hsSvoD%LE=YIA4u9oYg+4;G? zPVAalzzL=Eu#p;MkjLKpY7@n z>p`_yy6NgUuQs2~B1Ct&GBfrz((3s9yk;Xw!Uu{}Ma0Lla0m{D8g zRCx$8*xGxLAf&%B?+NLK0Py?k);k+>6=5|mVN`uiL}W~?zk%*^?L~JN!^hH7u+$W# z-`2Nd$UBzc>UvScA*Z1{of5(E(;in#jT8rz8*fs3^19+7CP~xE(_z9e0n$YfRIza-6^N z{9bidSH^_E+CKWDED+lj5b&%A8t@SRliQg%3kO|b>F>3_mY7gL7@zO!l&01Jre~ml zg%4KT)TXjXEMnOTm8{LVCY~eU zWBb5#ady56h4!b#wVE5EYKTwNY4_BP@odD8!VvqeSZpDmZDML$CW_=HR#6b{{#?xDSxqR2o zHv5UhhRgn6kJTNRQ3T$dnEUp~)R$0i#JvF3U`g%cYB}_G#qJ>~zfEG|Uq)As77p+= zD^?s4pBL@DL{Gax)RvR0n+8%IK&C_#LRxsYJ-b~o^AF2|e)ZGHf_rAyOKWU&IBMg7 zTxcxL#d(epgj>`6IEiE8RjF*LjXQINIq$oeo>px+u!5fL>$Xfz`O8K-;dFI&iFGHh zwKYM7^sQ1(YXm^NAf+Nv*hMTpf>{%4?$6UV=%QlHdV{u~uO%vPv13V5$g?l6{2+VR zRm}DYni=LFu@8+hYH6O~`8DJXFFM?}YUNrJ3YE{Dyohf@vkB3r}Dl##6WP2|Xr-=8P7Jxf|> zU;OlK|6ZNYk*@v}mLx~tqfLxNzvJMzj7sxRVjc+#8`AgJ)?g0gfM>qE)oya0t)Yu^ zr-m+xO?{}#jYRo(esa>YY;o4TeA6a%E;nIShl>=NYr+qZx0|2+ra6_}>pYv4Ih7Wy z9h7CkH7ylx_wca#+iCD%(&o^s{UxU-Q+I`y?e}k%Eef;Jr}#S3Xh9G5ZC?omnz*vE zqOn3(4gYQru(t4zz1*()>*`KyY=UHo;7CZWasfK^`gaHyd(z9j+x#K#o1f|WtElPy zxh~MUriY}htgf-Hu2k)nszzZ$e?xzBW^O^oj89&BkI)o!OzQ%X8pjTHlEKACnXDE z%fZZg8|j8%ERqu_k*l0?M1rV2Q;mwK<)`Us?QP6j%x}hdc5jKUqOUi1*-Pf70X5&P z-@_u*Xr_sxbb8igaB))9-6>1&_gmCY9N0V}LEHakYA3YXS1N+Din@2)jfF<6ND@7+ zU6Siha|M;pT<&iKwntQ5z9~G%>-^?;U5l*#9w--vZ_-KppT`yk5K_cqSc(3?j`%1W zsoej)HILmU%)#%wmt_T`?tyh7AEiHV@t^e$Vsp5y8z=D6dE`L#S1TRg9s~S^j|?3i zT5QZG_1MjJ$n21+J8MbGSi%*vNwM9w`x=71xghMqX0&SB`RVB&Jn_Y8LVNs(x0zhQQdN?d#=JFEH{{#3*?=Z%Zecs&4`h


5?Wl}&jWxO>5=(-zd+F+qbgt(5=;ISFz7JbOQ`~dnvVCfuK*0Zh+3Jpxu zGBWG#!aL^}mNlSDgcfEY;`APDtPR{Ihllnplh3fXD73G!;hb-D|Qd ze&}=~;ZNcwpQwhY7nwOQin$1HqZFn?KfK&T?V@=-8tpUN-7Jx8#F>H z@IMoB_|~R7%uG2l$H&T<$6l1z%N|+P*DyI8KnJL0vY6U={`_fayI{YG?*9N=OkBfp z>6w#LVZv@Zo8}85~i%T85qnElP7ZsJ0~&)900{Rvul|7QCWR25BN^v*Y7R*E_8p+FC7Q& zfqwL^zwoO+{Fk|mgCQ-7K}H!O41*kkn0AK8z=Zg<@JLwtH)a8{fwXS(kzjYyOdtcY z4BmiQHVhw3@*f$h)ZKjS)LvDYZD3ja@p6Z|hq;Bv`SJN{1KDp1>5inJm8%Q2`c`Z6 z=YL*r*3YZ!^)JMH{?7~XysgYx-k?897n&kI6SW@eUE5Dz50!du=eB`%Cwd_Mwqm=H z9#acLzDB!sV4H!rRiu{E%am#ML!RGLZ2sG`!}}BI$1$+?@g|wr?i*>&ZnS>S`Biec zVDoFHX+7{Gy7&1~>*C|}Hn3KyPP@}*Y=`5dt+&0+^y47*Y?ZTqz0ntxhh+hY2l*D5 zZojU62tV82&)hl)HMu=Jd2ITAycvB=2)(YuU%V~PzMaXPXD_}!<=N@apYp^D-mD>C z=s#X{Xz{iRcKlilQwYB&5qev>x^Ic@`KUb+dUFrdyYRoPygQ>Y@;}?Db|B^XZFTmw ziN@b~!gjAqZV7n3)Ya>GaY*`p&Aj>RrIw9&q_xg>FYkDA<`;yJ^J+bjN|bwq5eF`u z?X9vOqkO-ry8LZ+J-+6b`$Q}5eeMyr+wS-Fig&(xDf?auRc#PJT6s~v7HSG(SAwz|%CO+tCC@Go+x z131%!)dso5@W@a&8j7yS$DZuglsn5oVuM_NJ1sVRPL>Id(iO|}x%r#j>$ZtT;^(8|?Y$arH%?4z@y!?K<6kGdE55%C~(_y!Iet$-o=j}c;M}1ApAjEq&&DI9v9;{BxydF`X;m>*;;cxN6Z1ldH>_&WMI<@)j9r_;o`_yVgd{ zA^T?JL7>xoxAV~boac2=jJelmd!VC<`Fy$kXtfRYkM3~uvzp~WPI#;BM(e|9V5?m= zXN~^zzn!6*FAP4;iwA=viaFfPE>FA2=iQ}aGU+eTVvB_s>F5z>=xc;YC>jut#K*{1 zoHDFw9?c&ds@}g^vP0_h#u8m!de`QcQ~$1*&r1pM`o549Ha{YdS5&Fs9{AJ$UQWgMTX@tf{GxjF{=J8Sav z-!T~&iwYC+gqqZeveffd>+FoH=VwcIIbsNssX=OICyF=-Bz1x@}{OXnC8K3J3t5}+Arbc45d0P_{j}z2J4K@RK+qi_Z8WH z?hfhpx64DPKi1|ZQwj;w?6bnG9teK%tB|6xFYSb`bp z3PJ48+7HVAxve0H9jeJ#UN+TjCFVexZ=KA*;Mj>&e;8RWv(G47pIOMEQdGD~1}ss8FP=f)H7n^S`W-{Q$FUBB1VUyGZ$iVlMbv!>G&069 z)!<~J+g4#CTj+Lf>4~hGZg;txd=L1sbxxP0cqGdOOXq$eAi%kxGmk#S<97?G1 zy^>hjx)l{a;vUU9)R|0UAWs_1ABao0$UdAgj4i8<<3c2bP?$pBSQ84Z?#iQdP1&Z2 z#SuHMp1P<^CX6GC|9J*rmSWLO9l-%gVst*)rjTu?@*t_)jcjWj~5MpsIo%29?GG~ta<2sdFDr-loYS^j5)!jF0^ zMO8E+Ktditiq@==2qip|UX}g|fhTU4H!fIT@$xAPkNGCWF{ckBPGvaAkD6_={JTUV z4grd?P8z;x6vHw|AGFeR#Zg2Moh6-8^(A)dcBbhLqG^mGYl2j|&!M7VOCVdn zn^#PCQo_EJfgH3W<2OfHuBh%pN!#o@Cu`Le~2W|re>CXm&}w! zpyuE9B0=UaRYwiy5ZUs|JLGAQgem(jYo>z=1C;_tn+pA@YFs|etBlTmGL)18;T*E~ z^j+jMUY?^p2WxDLiLt=e8 z3KA@N`c$O%v+P%lBSYfY^=3gE z(q4@_tqL@F-z5gY-WcYp&X0Jhs~Ar77$&3oaCG;cAN%Po71IY!MBE;z{lt*QSo+`< zIRjF$02{W zZ`UR!pvM7Lg%qSi5~70mAXQy1UZE#Z?r0!?#TT$XF00J`Z*4KdPczFXv(M_pUyN0! z=2E`;8L9R&C?N(t=NJYc>yyxDP9NqvEbrsAc&-WE^1O`!6{F zo~Cx_%>UEz1ekTZtn?t|*j?`Fn*);h4TZ$=)aHG9L zxr0f80dUmpb2o6?BrZ)ij~b980RbH^R7bxt4>IU!)v7Q^ysJC_t`V>d{{j%Q_5 zM6IPtx?Jlkl~(nRF(W30lon~H5Fzs6fgNMMj5tZw*Zsh)&H^Jps+axxGdSag@_%c$ z5bDPYL0@vzMus1O4Sp}cR95drf*rRk^rMISqfCbVpHN!F-=87qV8F zj@;M?k)INu=@z!}7~canNpD}?-e=mCm61(g<4Mj2r>S8)Aj4oJgc03H@vRCXU8XFk zr5;Lm>cKY|g`tMmT-wmHjw4Zs1hjpG0{qWg11XMh{(16-ALJ(Vf!X?BkN_ZD9I7kI zG90&i$&c3WTQh)%9JJ*{LSCZHFt7+w*MM}6Bn5(Kp>l<0b&GB+y7Q1816h0g=em<; zpPpF-X#@yJa?u(miyKf7xOn20cj%Q@4?0nX(AkEiPnye>&K;@QLj?*$`_B)fofjtx zU?W8qWlSGdFIq!{)%Z!K_nkZR>$DkAKY!kbK*wSTNl2y+Z&GEc@~7itV*V3aD`jP6 zbv~Y)MFao}j8kMwx3{;o86ZH_>!)tosH&>*MwEUa2Fvik_HTxXMuzhLkjUxMl#R=_ zoY|9*NspJVSk9IiW4F3&yL8hHX$LJf|MY};Q>&d(7Nl_mgMEF%^r=xJyP={YNhMdi zBV1fu@q}D;{nJt(h6XamF%lGsW63nrSsXTVB{Ezao~C5z5ac5x#Dz->x##qu4J6oL zZGHXZv+aln@wv`;QY4N-WU|W?b9vpski<=z*5+pEq=iRf8NX>h2^CqoQb;~BT#o|2_GiS@2)k|L^4gPE5!ZAGddJfOE2fi(}f( QxBrUDNGOWeiT()sKb3{D=>Px# diff --git a/assets/js/admin/jquery.flot.axislabels.js b/assets/js/admin/jquery.flot.axislabels.js new file mode 100644 index 0000000..c4b3bca --- /dev/null +++ b/assets/js/admin/jquery.flot.axislabels.js @@ -0,0 +1,466 @@ +/* +Axis Labels Plugin for flot. +http://github.com/markrcote/flot-axislabels + +Original code is Copyright (c) 2010 Xuan Luo. +Original code was released under the GPLv3 license by Xuan Luo, September 2010. +Original code was rereleased under the MIT license by Xuan Luo, April 2012. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +(function ($) { + var options = { + axisLabels: { + show: true + } + }; + + function canvasSupported() { + return !!document.createElement('canvas').getContext; + } + + function canvasTextSupported() { + if (!canvasSupported()) { + return false; + } + var dummy_canvas = document.createElement('canvas'); + var context = dummy_canvas.getContext('2d'); + return typeof context.fillText == 'function'; + } + + function css3TransitionSupported() { + var div = document.createElement('div'); + return typeof div.style.MozTransition != 'undefined' // Gecko + || typeof div.style.OTransition != 'undefined' // Opera + || typeof div.style.webkitTransition != 'undefined' // WebKit + || typeof div.style.transition != 'undefined'; + } + + + function AxisLabel(axisName, position, padding, plot, opts) { + this.axisName = axisName; + this.position = position; + this.padding = padding; + this.plot = plot; + this.opts = opts; + this.width = 0; + this.height = 0; + } + + AxisLabel.prototype.cleanup = function() { + }; + + + CanvasAxisLabel.prototype = new AxisLabel(); + CanvasAxisLabel.prototype.constructor = CanvasAxisLabel; + function CanvasAxisLabel(axisName, position, padding, plot, opts) { + AxisLabel.prototype.constructor.call(this, axisName, position, padding, + plot, opts); + } + + CanvasAxisLabel.prototype.calculateSize = function() { + if (!this.opts.axisLabelFontSizePixels) + this.opts.axisLabelFontSizePixels = 14; + if (!this.opts.axisLabelFontFamily) + this.opts.axisLabelFontFamily = 'sans-serif'; + + var textWidth = this.opts.axisLabelFontSizePixels + this.padding; + var textHeight = this.opts.axisLabelFontSizePixels + this.padding; + if (this.position == 'left' || this.position == 'right') { + this.width = this.opts.axisLabelFontSizePixels + this.padding; + this.height = 0; + } else { + this.width = 0; + this.height = this.opts.axisLabelFontSizePixels + this.padding; + } + }; + + CanvasAxisLabel.prototype.draw = function(box) { + if (!this.opts.axisLabelColour) + this.opts.axisLabelColour = 'black'; + var ctx = this.plot.getCanvas().getContext('2d'); + ctx.save(); + ctx.font = this.opts.axisLabelFontSizePixels + 'px ' + + this.opts.axisLabelFontFamily; + ctx.fillStyle = this.opts.axisLabelColour; + var width = ctx.measureText(this.opts.axisLabel).width; + var height = this.opts.axisLabelFontSizePixels; + var x, y, angle = 0; + if (this.position == 'top') { + x = box.left + box.width/2 - width/2; + y = box.top + height*0.72; + } else if (this.position == 'bottom') { + x = box.left + box.width/2 - width/2; + y = box.top + box.height - height*0.72; + } else if (this.position == 'left') { + x = box.left + height*0.72; + y = box.height/2 + box.top + width/2; + angle = -Math.PI/2; + } else if (this.position == 'right') { + x = box.left + box.width - height*0.72; + y = box.height/2 + box.top - width/2; + angle = Math.PI/2; + } + ctx.translate(x, y); + ctx.rotate(angle); + ctx.fillText(this.opts.axisLabel, 0, 0); + ctx.restore(); + }; + + + HtmlAxisLabel.prototype = new AxisLabel(); + HtmlAxisLabel.prototype.constructor = HtmlAxisLabel; + function HtmlAxisLabel(axisName, position, padding, plot, opts) { + AxisLabel.prototype.constructor.call(this, axisName, position, + padding, plot, opts); + this.elem = null; + } + + HtmlAxisLabel.prototype.calculateSize = function() { + var elem = $('
' + + this.opts.axisLabel + '
'); + this.plot.getPlaceholder().append(elem); + // store height and width of label itself, for use in draw() + this.labelWidth = elem.outerWidth(true); + this.labelHeight = elem.outerHeight(true); + elem.remove(); + + this.width = this.height = 0; + if (this.position == 'left' || this.position == 'right') { + this.width = this.labelWidth + this.padding; + } else { + this.height = this.labelHeight + this.padding; + } + }; + + HtmlAxisLabel.prototype.cleanup = function() { + if (this.elem) { + this.elem.remove(); + } + }; + + HtmlAxisLabel.prototype.draw = function(box) { + this.plot.getPlaceholder().find('#' + this.axisName + 'Label').remove(); + this.elem = $('
' + + this.opts.axisLabel + '
'); + this.plot.getPlaceholder().append(this.elem); + if (this.position == 'top') { + this.elem.css('left', box.left + box.width/2 - this.labelWidth/2 + + 'px'); + this.elem.css('top', box.top + 'px'); + } else if (this.position == 'bottom') { + this.elem.css('left', box.left + box.width/2 - this.labelWidth/2 + + 'px'); + this.elem.css('top', box.top + box.height - this.labelHeight + + 'px'); + } else if (this.position == 'left') { + this.elem.css('top', box.top + box.height/2 - this.labelHeight/2 + + 'px'); + this.elem.css('left', box.left + 'px'); + } else if (this.position == 'right') { + this.elem.css('top', box.top + box.height/2 - this.labelHeight/2 + + 'px'); + this.elem.css('left', box.left + box.width - this.labelWidth + + 'px'); + } + }; + + + CssTransformAxisLabel.prototype = new HtmlAxisLabel(); + CssTransformAxisLabel.prototype.constructor = CssTransformAxisLabel; + function CssTransformAxisLabel(axisName, position, padding, plot, opts) { + HtmlAxisLabel.prototype.constructor.call(this, axisName, position, + padding, plot, opts); + } + + CssTransformAxisLabel.prototype.calculateSize = function() { + HtmlAxisLabel.prototype.calculateSize.call(this); + this.width = this.height = 0; + if (this.position == 'left' || this.position == 'right') { + this.width = this.labelHeight + this.padding; + } else { + this.height = this.labelHeight + this.padding; + } + }; + + CssTransformAxisLabel.prototype.transforms = function(degrees, x, y) { + var stransforms = { + '-moz-transform': '', + '-webkit-transform': '', + '-o-transform': '', + '-ms-transform': '' + }; + if (x != 0 || y != 0) { + var stdTranslate = ' translate(' + x + 'px, ' + y + 'px)'; + stransforms['-moz-transform'] += stdTranslate; + stransforms['-webkit-transform'] += stdTranslate; + stransforms['-o-transform'] += stdTranslate; + stransforms['-ms-transform'] += stdTranslate; + } + if (degrees != 0) { + var rotation = degrees / 90; + var stdRotate = ' rotate(' + degrees + 'deg)'; + stransforms['-moz-transform'] += stdRotate; + stransforms['-webkit-transform'] += stdRotate; + stransforms['-o-transform'] += stdRotate; + stransforms['-ms-transform'] += stdRotate; + } + var s = 'top: 0; left: 0; '; + for (var prop in stransforms) { + if (stransforms[prop]) { + s += prop + ':' + stransforms[prop] + ';'; + } + } + s += ';'; + return s; + }; + + CssTransformAxisLabel.prototype.calculateOffsets = function(box) { + var offsets = { x: 0, y: 0, degrees: 0 }; + if (this.position == 'bottom') { + offsets.x = box.left + box.width/2 - this.labelWidth/2; + offsets.y = box.top + box.height - this.labelHeight; + } else if (this.position == 'top') { + offsets.x = box.left + box.width/2 - this.labelWidth/2; + offsets.y = box.top; + } else if (this.position == 'left') { + offsets.degrees = -90; + offsets.x = box.left - this.labelWidth/2 + this.labelHeight/2; + offsets.y = box.height/2 + box.top; + } else if (this.position == 'right') { + offsets.degrees = 90; + offsets.x = box.left + box.width - this.labelWidth/2 + - this.labelHeight/2; + offsets.y = box.height/2 + box.top; + } + offsets.x = Math.round(offsets.x); + offsets.y = Math.round(offsets.y); + + return offsets; + }; + + CssTransformAxisLabel.prototype.draw = function(box) { + this.plot.getPlaceholder().find("." + this.axisName + "Label").remove(); + var offsets = this.calculateOffsets(box); + this.elem = $('
' + this.opts.axisLabel + '
'); + this.plot.getPlaceholder().append(this.elem); + }; + + + IeTransformAxisLabel.prototype = new CssTransformAxisLabel(); + IeTransformAxisLabel.prototype.constructor = IeTransformAxisLabel; + function IeTransformAxisLabel(axisName, position, padding, plot, opts) { + CssTransformAxisLabel.prototype.constructor.call(this, axisName, + position, padding, + plot, opts); + this.requiresResize = false; + } + + IeTransformAxisLabel.prototype.transforms = function(degrees, x, y) { + // I didn't feel like learning the crazy Matrix stuff, so this uses + // a combination of the rotation transform and CSS positioning. + var s = ''; + if (degrees != 0) { + var rotation = degrees/90; + while (rotation < 0) { + rotation += 4; + } + s += ' filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=' + rotation + '); '; + // see below + this.requiresResize = (this.position == 'right'); + } + if (x != 0) { + s += 'left: ' + x + 'px; '; + } + if (y != 0) { + s += 'top: ' + y + 'px; '; + } + return s; + }; + + IeTransformAxisLabel.prototype.calculateOffsets = function(box) { + var offsets = CssTransformAxisLabel.prototype.calculateOffsets.call( + this, box); + // adjust some values to take into account differences between + // CSS and IE rotations. + if (this.position == 'top') { + // FIXME: not sure why, but placing this exactly at the top causes + // the top axis label to flip to the bottom... + offsets.y = box.top + 1; + } else if (this.position == 'left') { + offsets.x = box.left; + offsets.y = box.height/2 + box.top - this.labelWidth/2; + } else if (this.position == 'right') { + offsets.x = box.left + box.width - this.labelHeight; + offsets.y = box.height/2 + box.top - this.labelWidth/2; + } + return offsets; + }; + + IeTransformAxisLabel.prototype.draw = function(box) { + CssTransformAxisLabel.prototype.draw.call(this, box); + if (this.requiresResize) { + this.elem = this.plot.getPlaceholder().find("." + this.axisName + + "Label"); + // Since we used CSS positioning instead of transforms for + // translating the element, and since the positioning is done + // before any rotations, we have to reset the width and height + // in case the browser wrapped the text (specifically for the + // y2axis). + this.elem.css('width', this.labelWidth); + this.elem.css('height', this.labelHeight); + } + }; + + + function init(plot) { + plot.hooks.processOptions.push(function (plot, options) { + + if (!options.axisLabels.show) + return; + + // This is kind of a hack. There are no hooks in Flot between + // the creation and measuring of the ticks (setTicks, measureTickLabels + // in setupGrid() ) and the drawing of the ticks and plot box + // (insertAxisLabels in setupGrid() ). + // + // Therefore, we use a trick where we run the draw routine twice: + // the first time to get the tick measurements, so that we can change + // them, and then have it draw it again. + var secondPass = false; + + var axisLabels = {}; + var axisOffsetCounts = { left: 0, right: 0, top: 0, bottom: 0 }; + + var defaultPadding = 2; // padding between axis and tick labels + plot.hooks.draw.push(function (plot, ctx) { + var hasAxisLabels = false; + if (!secondPass) { + // MEASURE AND SET OPTIONS + $.each(plot.getAxes(), function(axisName, axis) { + var opts = axis.options // Flot 0.7 + || plot.getOptions()[axisName]; // Flot 0.6 + + // Handle redraws initiated outside of this plug-in. + if (axisName in axisLabels) { + axis.labelHeight = axis.labelHeight - + axisLabels[axisName].height; + axis.labelWidth = axis.labelWidth - + axisLabels[axisName].width; + opts.labelHeight = axis.labelHeight; + opts.labelWidth = axis.labelWidth; + axisLabels[axisName].cleanup(); + delete axisLabels[axisName]; + } + + if (!opts || !opts.axisLabel || !axis.show) + return; + + hasAxisLabels = true; + var renderer = null; + + if (!opts.axisLabelUseHtml && + navigator.appName == 'Microsoft Internet Explorer') { + var ua = navigator.userAgent; + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) { + rv = parseFloat(RegExp.$1); + } + if (rv >= 9 && !opts.axisLabelUseCanvas && !opts.axisLabelUseHtml) { + renderer = CssTransformAxisLabel; + } else if (!opts.axisLabelUseCanvas && !opts.axisLabelUseHtml) { + renderer = IeTransformAxisLabel; + } else if (opts.axisLabelUseCanvas) { + renderer = CanvasAxisLabel; + } else { + renderer = HtmlAxisLabel; + } + } else { + if (opts.axisLabelUseHtml || (!css3TransitionSupported() && !canvasTextSupported()) && !opts.axisLabelUseCanvas) { + renderer = HtmlAxisLabel; + } else if (opts.axisLabelUseCanvas || !css3TransitionSupported()) { + renderer = CanvasAxisLabel; + } else { + renderer = CssTransformAxisLabel; + } + } + + var padding = opts.axisLabelPadding === undefined ? + defaultPadding : opts.axisLabelPadding; + + axisLabels[axisName] = new renderer(axisName, + axis.position, padding, + plot, opts); + + // flot interprets axis.labelHeight and .labelWidth as + // the height and width of the tick labels. We increase + // these values to make room for the axis label and + // padding. + + axisLabels[axisName].calculateSize(); + + // AxisLabel.height and .width are the size of the + // axis label and padding. + // Just set opts here because axis will be sorted out on + // the redraw. + + opts.labelHeight = axis.labelHeight + + axisLabels[axisName].height; + opts.labelWidth = axis.labelWidth + + axisLabels[axisName].width; + }); + + // If there are axis labels, re-draw with new label widths and + // heights. + + if (hasAxisLabels) { + secondPass = true; + plot.setupGrid(); + plot.draw(); + } + } else { + secondPass = false; + // DRAW + $.each(plot.getAxes(), function(axisName, axis) { + var opts = axis.options // Flot 0.7 + || plot.getOptions()[axisName]; // Flot 0.6 + if (!opts || !opts.axisLabel || !axis.show) + return; + + axisLabels[axisName].draw(axis.box); + }); + } + }); + }); + } + + + $.plot.plugins.push({ + init: init, + options: options, + name: 'axisLabels', + version: '2.0' + }); +})(jQuery); diff --git a/assets/js/admin/jquery.flot.axislabels.min.js b/assets/js/admin/jquery.flot.axislabels.min.js new file mode 100644 index 0000000..21b20cd --- /dev/null +++ b/assets/js/admin/jquery.flot.axislabels.min.js @@ -0,0 +1 @@ +!function(a){function c(){return!!document.createElement("canvas").getContext}function d(){if(!c())return!1;var a=document.createElement("canvas"),b=a.getContext("2d");return"function"==typeof b.fillText}function e(){var a=document.createElement("div");return"undefined"!=typeof a.style.MozTransition||"undefined"!=typeof a.style.OTransition||"undefined"!=typeof a.style.webkitTransition||"undefined"!=typeof a.style.transition}function f(a,b,c,d,e){this.axisName=a,this.position=b,this.padding=c,this.plot=d,this.opts=e,this.width=0,this.height=0}function g(a,b,c,d,e){f.prototype.constructor.call(this,a,b,c,d,e)}function h(a,b,c,d,e){f.prototype.constructor.call(this,a,b,c,d,e),this.elem=null}function i(a,b,c,d,e){h.prototype.constructor.call(this,a,b,c,d,e)}function j(a,b,c,d,e){i.prototype.constructor.call(this,a,b,c,d,e),this.requiresResize=!1}function k(b){b.hooks.processOptions.push(function(b,c){if(c.axisLabels.show){var f=!1,k={},m=2;b.hooks.draw.push(function(b,c){var l=!1;f?(f=!1,a.each(b.getAxes(),function(a,c){var d=c.options||b.getOptions()[a];d&&d.axisLabel&&c.show&&k[a].draw(c.box)})):(a.each(b.getAxes(),function(a,c){var f=c.options||b.getOptions()[a];if(a in k&&(c.labelHeight=c.labelHeight-k[a].height,c.labelWidth=c.labelWidth-k[a].width,f.labelHeight=c.labelHeight,f.labelWidth=c.labelWidth,k[a].cleanup(),delete k[a]),f&&f.axisLabel&&c.show){l=!0;var n=null;if(f.axisLabelUseHtml||"Microsoft Internet Explorer"!=navigator.appName)n=f.axisLabelUseHtml||!e()&&!d()&&!f.axisLabelUseCanvas?h:f.axisLabelUseCanvas||!e()?g:i;else{var o=navigator.userAgent,p=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");null!=p.exec(o)&&(rv=parseFloat(RegExp.$1)),n=rv>=9&&!f.axisLabelUseCanvas&&!f.axisLabelUseHtml?i:f.axisLabelUseCanvas||f.axisLabelUseHtml?f.axisLabelUseCanvas?g:h:j}var q=void 0===f.axisLabelPadding?m:f.axisLabelPadding;k[a]=new n(a,c.position,q,b,f),k[a].calculateSize(),f.labelHeight=c.labelHeight+k[a].height,f.labelWidth=c.labelWidth+k[a].width}}),l&&(f=!0,b.setupGrid(),b.draw()))})}})}var b={axisLabels:{show:!0}};f.prototype.cleanup=function(){},g.prototype=new f,g.prototype.constructor=g,g.prototype.calculateSize=function(){this.opts.axisLabelFontSizePixels||(this.opts.axisLabelFontSizePixels=14),this.opts.axisLabelFontFamily||(this.opts.axisLabelFontFamily="sans-serif");this.opts.axisLabelFontSizePixels+this.padding,this.opts.axisLabelFontSizePixels+this.padding;"left"==this.position||"right"==this.position?(this.width=this.opts.axisLabelFontSizePixels+this.padding,this.height=0):(this.width=0,this.height=this.opts.axisLabelFontSizePixels+this.padding)},g.prototype.draw=function(a){this.opts.axisLabelColour||(this.opts.axisLabelColour="black");var b=this.plot.getCanvas().getContext("2d");b.save(),b.font=this.opts.axisLabelFontSizePixels+"px "+this.opts.axisLabelFontFamily,b.fillStyle=this.opts.axisLabelColour;var e,f,c=b.measureText(this.opts.axisLabel).width,d=this.opts.axisLabelFontSizePixels,g=0;"top"==this.position?(e=a.left+a.width/2-c/2,f=a.top+.72*d):"bottom"==this.position?(e=a.left+a.width/2-c/2,f=a.top+a.height-.72*d):"left"==this.position?(e=a.left+.72*d,f=a.height/2+a.top+c/2,g=-Math.PI/2):"right"==this.position&&(e=a.left+a.width-.72*d,f=a.height/2+a.top-c/2,g=Math.PI/2),b.translate(e,f),b.rotate(g),b.fillText(this.opts.axisLabel,0,0),b.restore()},h.prototype=new f,h.prototype.constructor=h,h.prototype.calculateSize=function(){var b=a('
'+this.opts.axisLabel+"
");this.plot.getPlaceholder().append(b),this.labelWidth=b.outerWidth(!0),this.labelHeight=b.outerHeight(!0),b.remove(),this.width=this.height=0,"left"==this.position||"right"==this.position?this.width=this.labelWidth+this.padding:this.height=this.labelHeight+this.padding},h.prototype.cleanup=function(){this.elem&&this.elem.remove()},h.prototype.draw=function(b){this.plot.getPlaceholder().find("#"+this.axisName+"Label").remove(),this.elem=a('
'+this.opts.axisLabel+"
"),this.plot.getPlaceholder().append(this.elem),"top"==this.position?(this.elem.css("left",b.left+b.width/2-this.labelWidth/2+"px"),this.elem.css("top",b.top+"px")):"bottom"==this.position?(this.elem.css("left",b.left+b.width/2-this.labelWidth/2+"px"),this.elem.css("top",b.top+b.height-this.labelHeight+"px")):"left"==this.position?(this.elem.css("top",b.top+b.height/2-this.labelHeight/2+"px"),this.elem.css("left",b.left+"px")):"right"==this.position&&(this.elem.css("top",b.top+b.height/2-this.labelHeight/2+"px"),this.elem.css("left",b.left+b.width-this.labelWidth+"px"))},i.prototype=new h,i.prototype.constructor=i,i.prototype.calculateSize=function(){h.prototype.calculateSize.call(this),this.width=this.height=0,"left"==this.position||"right"==this.position?this.width=this.labelHeight+this.padding:this.height=this.labelHeight+this.padding},i.prototype.transforms=function(a,b,c){var d={"-moz-transform":"","-webkit-transform":"","-o-transform":"","-ms-transform":""};if(0!=b||0!=c){var e=" translate("+b+"px, "+c+"px)";d["-moz-transform"]+=e,d["-webkit-transform"]+=e,d["-o-transform"]+=e,d["-ms-transform"]+=e}if(0!=a){var g=" rotate("+a+"deg)";d["-moz-transform"]+=g,d["-webkit-transform"]+=g,d["-o-transform"]+=g,d["-ms-transform"]+=g}var h="top: 0; left: 0; ";for(var i in d)d[i]&&(h+=i+":"+d[i]+";");return h+=";"},i.prototype.calculateOffsets=function(a){var b={x:0,y:0,degrees:0};return"bottom"==this.position?(b.x=a.left+a.width/2-this.labelWidth/2,b.y=a.top+a.height-this.labelHeight):"top"==this.position?(b.x=a.left+a.width/2-this.labelWidth/2,b.y=a.top):"left"==this.position?(b.degrees=-90,b.x=a.left-this.labelWidth/2+this.labelHeight/2,b.y=a.height/2+a.top):"right"==this.position&&(b.degrees=90,b.x=a.left+a.width-this.labelWidth/2-this.labelHeight/2,b.y=a.height/2+a.top),b.x=Math.round(b.x),b.y=Math.round(b.y),b},i.prototype.draw=function(b){this.plot.getPlaceholder().find("."+this.axisName+"Label").remove();var c=this.calculateOffsets(b);this.elem=a('
'+this.opts.axisLabel+"
"),this.plot.getPlaceholder().append(this.elem)},j.prototype=new i,j.prototype.constructor=j,j.prototype.transforms=function(a,b,c){var d="";if(0!=a){for(var e=a/90;e<0;)e+=4;d+=" filter: progid:DXImageTransform.Microsoft.BasicImage(rotation="+e+"); ",this.requiresResize="right"==this.position}return 0!=b&&(d+="left: "+b+"px; "),0!=c&&(d+="top: "+c+"px; "),d},j.prototype.calculateOffsets=function(a){var b=i.prototype.calculateOffsets.call(this,a);return"top"==this.position?b.y=a.top+1:"left"==this.position?(b.x=a.left,b.y=a.height/2+a.top-this.labelWidth/2):"right"==this.position&&(b.x=a.left+a.width-this.labelHeight,b.y=a.height/2+a.top-this.labelWidth/2),b},j.prototype.draw=function(a){i.prototype.draw.call(this,a),this.requiresResize&&(this.elem=this.plot.getPlaceholder().find("."+this.axisName+"Label"),this.elem.css("width",this.labelWidth),this.elem.css("height",this.labelHeight))},a.plot.plugins.push({init:k,options:b,name:"axisLabels",version:"2.0"})}(jQuery); diff --git a/assets/js/admin/jquery.flot.orderBars.js b/assets/js/admin/jquery.flot.orderBars.js new file mode 100644 index 0000000..a3f8daa --- /dev/null +++ b/assets/js/admin/jquery.flot.orderBars.js @@ -0,0 +1,201 @@ +/* + * Flot plugin to order bars side by side. + * + * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010. + * Modifications made by Steven Hall , 01-May-2013. + * + * This plugin is an alpha version. + * + * To activate the plugin you must specify the parameter "order" for the specific serie : + * + * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) + * + * If 2 series have the same order param, they are ordered by the position in the array; + * + * The plugin adjust the point by adding a value depanding of the barwidth + * Exemple for 3 series (barwidth : 0.1) : + * + * first bar décalage : -0.15 + * second bar décalage : -0.05 + * third bar décalage : 0.05 + * + */ + +// INFO: decalage/decallage is French for gap. It's used to denote the spacing applied to each +// bar. +(function($){ + function init(plot){ + var orderedBarSeries; + var nbOfBarsToOrder; + var borderWidth; + var borderWidthInXabsWidth; + var pixelInXWidthEquivalent = 1; + var isHorizontal = false; + + // A mapping of order integers to decallage. + var decallageByOrder = {}; + + /* + * This method add shift to x values + */ + function reOrderBars(plot, serie, datapoints){ + var shiftedPoints = null; + + if(serieNeedToBeReordered(serie)){ + checkIfGraphIsHorizontal(serie); + calculPixel2XWidthConvert(plot); + retrieveBarSeries(plot); + calculBorderAndBarWidth(serie); + + if(nbOfBarsToOrder >= 2){ + var position = findPosition(serie); + var decallage = 0; + + var centerBarShift = calculCenterBarShift(); + + // If we haven't already calculated the decallage for this order value, do it. + if(typeof decallageByOrder[serie.bars.order] === 'undefined') { + if (isBarAtLeftOfCenter(position)){ + decallageByOrder[serie.bars.order] = -1*(sumWidth(orderedBarSeries,position-1,Math.floor(nbOfBarsToOrder / 2)-1)) - centerBarShift; + }else{ + decallageByOrder[serie.bars.order] = sumWidth(orderedBarSeries,Math.ceil(nbOfBarsToOrder / 2),position-2) + centerBarShift + borderWidthInXabsWidth*2; + } + } + + // Lookup the decallage based on the series' order value. + decallage = decallageByOrder[serie.bars.order]; + + shiftedPoints = shiftPoints(datapoints,serie,decallage); + datapoints.points = shiftedPoints; + } + } + return shiftedPoints; + } + + function serieNeedToBeReordered(serie){ + return serie.bars != null + && serie.bars.show + && serie.bars.order != null; + } + + function calculPixel2XWidthConvert(plot){ + var gridDimSize = isHorizontal ? plot.getPlaceholder().innerHeight() : plot.getPlaceholder().innerWidth(); + var minMaxValues = isHorizontal ? getAxeMinMaxValues(plot.getData(),1) : getAxeMinMaxValues(plot.getData(),0); + var AxeSize = minMaxValues[1] - minMaxValues[0]; + pixelInXWidthEquivalent = AxeSize / gridDimSize; + } + + function getAxeMinMaxValues(series,AxeIdx){ + var minMaxValues = new Array(); + for(var i = 0; i < series.length; i++){ + minMaxValues[0] = series[i].data[0][AxeIdx]; + minMaxValues[1] = series[i].data[series[i].data.length - 1][AxeIdx]; + } + return minMaxValues; + } + + function retrieveBarSeries(plot){ + orderedBarSeries = findOthersBarsToReOrders(plot.getData()); + nbOfBarsToOrder = orderedBarSeries.length; + } + + function findOthersBarsToReOrders(series){ + var retSeries = new Array(); + var orderValuesSeen = []; + + for(var i = 0; i < series.length; i++){ + if(series[i].bars.order != null && series[i].bars.show && + orderValuesSeen.indexOf(series[i].bars.order) < 0){ + + orderValuesSeen.push(series[i].bars.order); + retSeries.push(series[i]); + } + } + return retSeries.sort(sortByOrder); + } + + function sortByOrder(serie1,serie2){ + var x = serie1.bars.order; + var y = serie2.bars.order; + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + } + + function calculBorderAndBarWidth(serie){ + borderWidth = typeof serie.bars.lineWidth !== 'undefined' ? serie.bars.lineWidth : 2; + borderWidthInXabsWidth = borderWidth * pixelInXWidthEquivalent; + } + + function checkIfGraphIsHorizontal(serie){ + if(serie.bars.horizontal){ + isHorizontal = true; + } + } + + function findPosition(serie){ + var pos = 0 + for (var i = 0; i < orderedBarSeries.length; ++i) { + if (serie == orderedBarSeries[i]){ + pos = i; + break; + } + } + + return pos+1; + } + + function calculCenterBarShift(){ + var width = 0; + + if(nbOfBarsToOrder%2 != 0) + width = (orderedBarSeries[Math.ceil(nbOfBarsToOrder / 2)].bars.barWidth)/2; + + return width; + } + + function isBarAtLeftOfCenter(position){ + return position <= Math.ceil(nbOfBarsToOrder / 2); + } + + function sumWidth(series,start,end){ + var totalWidth = 0; + + for(var i = start; i <= end; i++){ + totalWidth += series[i].bars.barWidth+borderWidthInXabsWidth*2; + } + + return totalWidth; + } + + function shiftPoints(datapoints,serie,dx){ + var ps = datapoints.pointsize; + var points = datapoints.points; + var j = 0; + for(var i = isHorizontal ? 1 : 0;i < points.length; i += ps){ + points[i] += dx; + //Adding the new x value in the serie to be abble to display the right tooltip value, + //using the index 3 to not overide the third index. + serie.data[j][3] = points[i]; + j++; + } + + return points; + } + + plot.hooks.processDatapoints.push(reOrderBars); + + } + + var options = { + series : { + bars: {order: null} // or number/string + } + }; + + $.plot.plugins.push({ + init: init, + options: options, + name: "orderBars", + version: "0.2" + }); + +})(jQuery); \ No newline at end of file diff --git a/assets/js/admin/jquery.flot.orderBars.min.js b/assets/js/admin/jquery.flot.orderBars.min.js new file mode 100644 index 0000000..a1a1c90 --- /dev/null +++ b/assets/js/admin/jquery.flot.orderBars.min.js @@ -0,0 +1,23 @@ +/* + * Flot plugin to order bars side by side. + * + * Released under the MIT license by Benjamin BUFFET, 20-Sep-2010. + * Modifications made by Steven Hall , 01-May-2013. + * + * This plugin is an alpha version. + * + * To activate the plugin you must specify the parameter "order" for the specific serie : + * + * $.plot($("#placeholder"), [{ data: [ ... ], bars :{ order = null or integer }]) + * + * If 2 series have the same order param, they are ordered by the position in the array; + * + * The plugin adjust the point by adding a value depanding of the barwidth + * Exemple for 3 series (barwidth : 0.1) : + * + * first bar décalage : -0.15 + * second bar décalage : -0.05 + * third bar décalage : 0.05 + * + */ +!function(r){function n(r){function n(r,n,a){var i=null;if(t(n)&&(f(n),e(r),o(r),u(n),g>=2)){var s=l(n),v=0,W=d();"undefined"==typeof D[n.bars.order]&&(h(s)?D[n.bars.order]=-1*b(p,s-1,Math.floor(g/2)-1)-W:D[n.bars.order]=b(p,Math.ceil(g/2),s-2)+W+2*y),v=D[n.bars.order],i=c(a,n,v),a.points=i}return i}function t(r){return null!=r.bars&&r.bars.show&&null!=r.bars.order}function e(r){var n=w?r.getPlaceholder().innerHeight():r.getPlaceholder().innerWidth(),t=w?a(r.getData(),1):a(r.getData(),0),e=t[1]-t[0];W=e/n}function a(r,n){for(var t=new Array,e=0;et?-1:t>e?1:0}function u(r){v="undefined"!=typeof r.bars.lineWidth?r.bars.lineWidth:2,y=v*W}function f(r){r.bars.horizontal&&(w=!0)}function l(r){for(var n=0,t=0;t=a;a++)e+=r[a].bars.barWidth+2*y;return e}function c(r,n,t){for(var e=r.pointsize,a=r.points,o=0,i=w?1:0;i 0 ) { + + $( '.range_datepicker' ).datepicker( 'destroy' ); + + var dates = $( '.range_datepicker' ).datepicker({ + changeMonth: true, + changeYear: true, + defaultDate: "", + dateFormat: "yy-mm-dd", + numberOfMonths: 1, + minDate: "+0D", + showButtonPanel: true, + showOn: "focus", + buttonImageOnly: true, + onSelect: function( selectedDate ) { + var option = $(this).is('.from') ? "minDate" : "maxDate", + instance = $( this ).data( "datepicker" ), + date = $.datepicker.parseDate( instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings ); + dates.not( this ).datepicker( 'option', option, date ); + } + }); + } + + // We're on the Payment Retry page, change datepicker to allow both future dates and historical dates + if ( $( '#woocommerce_subscriptions_payment_retry_chart' ).length > 0 ) { + + $( '.range_datepicker' ).datepicker( 'destroy' ); + + var dates = $( '.range_datepicker' ).datepicker({ + changeMonth: true, + changeYear: true, + defaultDate: "", + dateFormat: "yy-mm-dd", + numberOfMonths: 1, + showButtonPanel: true, + showOn: "focus", + buttonImageOnly: true, + onSelect: function( selectedDate ) { + var option = $(this).is('.from') ? "minDate" : "maxDate", + instance = $( this ).data( "datepicker" ), + date = $.datepicker.parseDate( instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings ); + dates.not( this ).datepicker( 'option', option, date ); + } + }); + } + +}); \ No newline at end of file diff --git a/assets/js/admin/wcs-meta-boxes-order.js b/assets/js/admin/wcs-meta-boxes-order.js new file mode 100644 index 0000000..c99b87b --- /dev/null +++ b/assets/js/admin/wcs-meta-boxes-order.js @@ -0,0 +1,8 @@ +jQuery(document).ready(function($){ + + $('body.post-type-shop_order #post').submit(function(){ + if('wcs_retry_renewal_payment' == $( "body.post-type-shop_order select[name='wc_order_action']" ).val()) { + return confirm(wcs_admin_order_meta_boxes.retry_renewal_payment_action_warning); + } + }); +}); diff --git a/changelog.txt b/changelog.txt index a4672a2..c1a8932 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,37 @@ *** WooCommerce Subscriptions Changelog *** +2016.11.12 - version 2.1.0 + * New: Subscription Reports to get insights into the performance of your subscription business: https://docs.woocommerce.com/document/subscriptions/reports/ + * New: Failed Recurring Payment Retry System to help recover revenue that would otherwise be lost: https://docs.woocommerce.com/document/subscriptions/failed-payment-retry/ + * New: More subscription emails to help you keep on top of important events, like customer suspension and expiration: https://docs.woocommerce.com/document/subscriptions/version-2-1/#section-4 + * New: Cancellation date to keep track of when customers cancel subscriptions, not just when they end after being cancelled: https://docs.woocommerce.com/document/subscriptions/version-2-1/#section-5 + * New: Allow resubscribing to subscriptions Pending Cancellation: https://docs.woocommerce.com/document/subscriptions/version-2-1/#resubscribe-to-subscriptions-pending-cancellation + * New: REST API Endpoints for Subscriptions built on WordPress REST API infrastructure: https://docs.woocommerce.com/document/subscriptions/version-2-1/#wp-rest-api-endpoints + * New: Additional order type filters on the WooCommerce > Orders administration screen to filter orders to show only subscription parent, renewal, resubscribe or switch orders: https://docs.woocommerce.com/document/subscriptions/version-2-1/#additional-order-type-filters + * Tweak: Always use Renewal Order totals and data for renewal payments, making it possible to easily add one-time fees or discounts to renewals: https://docs.woocommerce.com/document/subscriptions/version-2-1/#renewal-orders-always-used-for-renewal-data + * Tweak: Improved responsiveness and layout of the subscription pricing fields on the Edit Product screen: https://docs.woocommerce.com/document/subscriptions/version-2-1/#edit-product-interface-improvements + * Tweak: Use renewal order/subscription addresses as the default address fields loaded on checkout for renewal, resubscribe and switch checkouts. https://docs.woocommerce.com/document/subscriptions/version-2-1/#use-renewal-order-or-subscription-address-on-checkout + * Tweak: Process switches (upgrades and downgrades) on order status change instead of when the customer completes checkout: https://docs.woocommerce.com/document/subscriptions/version-2-1/#process-upgrades-and-downgrades-on-order-status-change + * Tweak: Small performance improvements by no longer calling deprecated hooks and caching some queries: https://docs.woocommerce.com/document/subscriptions/version-2-1/#performance-improvements + * Tweak: Apply add-to-cart validation to renewals and resubscribes (using the 'woocommerce_add_to_cart_validation' hook): https://docs.woocommerce.com/document/subscriptions/version-2-1/#add-to-cart-validation-applied-to-renewal-and-resubscribe-process + * Tweak: Link to the My Account > Subscriptions page on the Order Received/Thank you page when using WooCommerce 2.6 so that the customer can see all their subscriptions if they purchased multiple subscriptions in the transaction. + * Tweak: Use the 'pay_for_order' user capability check to determine whether a user can pay for a renewal and resubscribe rather than checking their ID against the customer ID on the subscription. (PR#1692 / PR#1716) + * Tweak: Increase next payment date threshold for end date to safeguard against payments being processed on the last day of a subscription. (PR#1689) + * Tweak: Only check for PayPal Reference Transaction support once per week instead of daily. + * Tweak: Consistently use the same tooltips in the store admin area as WooCommerce. + * Tweak: Initiate auto-switch process when loading the Grouped product page. (PR#1641) + * Tweak: New 'woocommerce_subscriptions_after_recurring_shipping_rates' hook. + * Tweak: Update scheduling system (Action Scheduler) to version 1.5. + * Fix: Do not create new orders when processing a renewal and resubscribe payment with different details to the original order by ensuring the cart hash used by WooCommerce is updated when creating the order. (PR#1687) + * Fix: Prevent My Account > Subscriptions endpoint page title overriding custom menus and other items on the page calling 'the_title' filter. (PR#1737) + * Fix: Do not change the status of subscriptions using PayPal Standard when the request to update the status at PayPal.com fails because of incorrect API credentials. (PR#1743) + * Fix: Display incorrect PayPal API credentials notice after a status change request or reference transaction check returns incorrect credentials error. (PR#1743) + * Fix: Calculate switching next payment date calculations for a free product to a non-free product correctly. (PR#1661) + * Fix: Process renewals with PayPal Reference Transactions correctly when the ALTERNATE_WP_CRON constant is defined. (PR#1733) + * Fix: Prevent grouped subscription products being switched to non-subscription product in the same grouped product. (PR#1666) + * Fix: Treat empty subscription suspension count option value as 0, meaning no suspensions are allowed. (PR#1728) + * Fix: Only attempt to get paid renewal orders if there are renewal orders. (PR#1718) + 2016.09.23 - version 2.0.20 * Tweak: add new 'woocommerce_subscription_before_actions' and 'woocommerce_subscription_after_actions' hooks to the view-subscription.php template. (PR#1608) * Tweak: use WC_Subscriptions_Product::is_subscription() when checking if a product is sync'd instead of checking the product type directly so that the 'woocommerce_is_subscription' filter is applied and additional product types can add support for synchronisation. (PR#1635) @@ -302,7 +334,7 @@ * Fix: download links in the "download your files" email 2015.10.27 - version 2.0.3 - * New: One Time Shipping feature: https://docs.woothemes.com/document/subscriptions/store-manager-guide/#one-time-shipping + * New: One Time Shipping feature: https://docs.woocommerce.com/document/subscriptions/store-manager-guide/#one-time-shipping * Tweak: redirect to View Subscription page after changing payment method for payment methods redirecting back to My Account page * Fix: reactivation of subscriptions using PayPal Standard as the payment method after a subscription renewal payment IPN message is sent (introduced with 2.0.2) * Fix: use of start date in based on current GMT/UTC offset instead of GMT/UTC offset at the time the subscription was created to handle daylight savings time and changes to a site's timezone @@ -340,16 +372,16 @@ * Fix: upgrade error when upgrading a sync'd subscription that has been trashed for a product that has been permanently deleted 2015.10.05 - version 2.0.0 - * New: purchase different subscription products in the same transaction: https://docs.woothemes.com/document/subscriptions/version-2/#section-2 - * New: administration interface for Adding or Editing a subscription: https://docs.woothemes.com/document/subscriptions/version-2/#section-3 - * New: downloadable content dripping: https://docs.woothemes.com/document/subscriptions/version-2/#section-4 - * New: customer facing View Subscription page: https://docs.woothemes.com/document/subscriptions/version-2/#section-5 - * New: support for PayPal Reference Transactions: https://docs.woothemes.com/document/subscriptions/version-2/#section-8 - * New: Pending Cancellation status applied to a subscription after it has been cancelled but the customer or store manager until the prepaid term ends: https://docs.woothemes.com/document/subscriptions/version-2/#pending-cancellation - * Tweak: Subscriptions administration list table now includes recurring total, payment method and all search/sorting features for stores with a large number of subscriptions: https://docs.woothemes.com/document/subscriptions/version-2/#list-table - * Tweak: Improved flow on renewal - create renewal orders before processing the payment: https://docs.woothemes.com/document/subscriptions/version-2/#section-7 - * Tweak: one end date is now used to refer to the date on which a subscription did or will expire or was cancelled: https://docs.woothemes.com/document/subscriptions/version-2/#one-end-date - * Tweak: the renewal of a cancelled or expired subscription is now called "Resubscribe" to avoid confusion with normal renewal process: https://docs.woothemes.com/document/subscriptions/version-2/#resubscribe-not-renew + * New: purchase different subscription products in the same transaction: https://docs.woocommerce.com/document/subscriptions/version-2/#section-2 + * New: administration interface for Adding or Editing a subscription: https://docs.woocommerce.com/document/subscriptions/version-2/#section-3 + * New: downloadable content dripping: https://docs.woocommerce.com/document/subscriptions/version-2/#section-4 + * New: customer facing View Subscription page: https://docs.woocommerce.com/document/subscriptions/version-2/#section-5 + * New: support for PayPal Reference Transactions: https://docs.woocommerce.com/document/subscriptions/version-2/#section-8 + * New: Pending Cancellation status applied to a subscription after it has been cancelled but the customer or store manager until the prepaid term ends: https://docs.woocommerce.com/document/subscriptions/version-2/#pending-cancellation + * Tweak: Subscriptions administration list table now includes recurring total, payment method and all search/sorting features for stores with a large number of subscriptions: https://docs.woocommerce.com/document/subscriptions/version-2/#list-table + * Tweak: Improved flow on renewal - create renewal orders before processing the payment: https://docs.woocommerce.com/document/subscriptions/version-2/#section-7 + * Tweak: one end date is now used to refer to the date on which a subscription did or will expire or was cancelled: https://docs.woocommerce.com/document/subscriptions/version-2/#one-end-date + * Tweak: the renewal of a cancelled or expired subscription is now called "Resubscribe" to avoid confusion with normal renewal process: https://docs.woocommerce.com/document/subscriptions/version-2/#resubscribe-not-renew 2015.09.29 - version 1.5.31 * Tweak: introduce a new transient lock at the start of PayPal IPN handling to prevent duplicate IPN handling on sites taking more than a minute to process an IPN message and set the permanent lock @@ -637,7 +669,7 @@ * Tweak: move sign-up fee field to own row on the Edit Product screen to improve display on small screens * Tweak: when asked what type of product they are, variable subscriptions and subscription variations will now identify as both the subscription and standard equivalent (e.g. if a variable subscription is asked if it is a variable product, it will say yes, if a subscription variation is asked if it is a standard variation, it will say yes). * Tweak: in API responses, include variable subscriptions' children & subscription variations' parent objects (due to tweak in variable/variation self-identification above) - * Tweak: limit subscription regardless of status to prevent the same customer account effectively being able to access more than one free trial period. More: http://docs.woothemes.com/document/subscriptions/store-manager-guide/#limit-subscription + * Tweak: limit subscription regardless of status to prevent the same customer account effectively being able to access more than one free trial period. More: http://docs.woocommerce.com/document/subscriptions/store-manager-guide/#limit-subscription * Tweak: only allow customers to purchase subscriptions with PayPal once the store's API credentials are entered * Tweak: prefill "Change" next payment date fields with date in site's timezone instead of next payment date in GMT/UTC timezone * Fix: fix stock management for variable subscriptions (due to the tweak above making variable subscriptions identify as variable products) @@ -653,7 +685,7 @@ 2014.04.09 - version 1.4.10 * Tweak: Do not add the "Payment received" order note when a subscription has a free trial and no sign-up fee, instead display "Payment authorized" for subscriptions using automatic recurring payments and "Free trial commenced" for those using manual renewals * Tweak: On the Manage Subscriptions screen, do not display the subscription sign-up date in the "Last Payment" column if the subscription has a free trial and no sign-up fee (as there was no actual payment made) - * Tweak: Reinstate enctype='multipart/form-data' on the subscription add to cart form to fix compatibilty with file uploads via Product Addons extension (related to http://docs.woothemes.com/document/subscriptions/faq/#section-45) + * Tweak: Reinstate enctype='multipart/form-data' on the subscription add to cart form to fix compatibilty with file uploads via Product Addons extension (related to http://docs.woocommerce.com/document/subscriptions/faq/#section-45) * Tweak: Only output P tags for product meta on My Subscriptions table when product has meta * Tweak: add enable/disable field for the Customer Renewal Invoice email * Fix: set correct order date and ID in renewal order emails' subject & heading when sending more than one email in the same request (workaround until woothemes/woocommerce#5168 is implemented in WC 2.2) @@ -757,7 +789,7 @@ * Tweak: use a string literal text domain for translation plugins which don't support variable text domains, like the latest version of WPML * Tweak: try to align next payment dates with PayPal's schedule by update the next payment date time whenever PayPal processes a payment * Tweak: reduce hidden meta data included on the Manage Subscriptions screen to improve load time and provide cleaner search/filter URLs - * Tweak: new 'woocommerce_subscription_lengths' filter for custom subscription lengths: http://docs.woothemes.com/document/subscriptions/faq/#section-57 + * Tweak: new 'woocommerce_subscription_lengths' filter for custom subscription lengths: http://docs.woocommerce.com/document/subscriptions/faq/#section-57 * Tweak: add related order links to the Edit Order screen for renewal orders of cancelled/expired subscriptions * Fix: only load email classes once in case something is destroying and then reinitiating the Woocommerce::woocommerce_mailer property * Fix: only set recurring payment method meta data when an order is marked as completed for those orders that contain a subscription @@ -802,8 +834,8 @@ * Fix: error message displayed when no payment gateways are available to change the payment method. 2013.09.20 - version 1.4 - * New: "Switch" subscriptions feature to allow customers to upgrade/downgrade their subscription: http://docs.woothemes.com/document/subscriptions/switching-guide/ - * New: The payment method used for automatic recurring payments can now be changed by subscribers: http://docs.woothemes.com/document/subscriptions/customers-view/#section-5 + * New: "Switch" subscriptions feature to allow customers to upgrade/downgrade their subscription: http://docs.woocommerce.com/document/subscriptions/switching-guide/ + * New: The payment method used for automatic recurring payments can now be changed by subscribers: http://docs.woocommerce.com/document/subscriptions/customers-view/#section-5 * New: Database structure for subscriptions to improve performance on all sites and fix memory exhaustion issues on sites with tens of thousands of subscriptions. Subscription meta data is now stored in order meta not user meta. * New: The recurring shipping method, title, tax and total used for renewals can now be changed by store managers from the 'Edit Order' page of the original order used to purchase the subscription (for those payment gateways which support changing recurring amounts). * New: Renewal order emails: using the WooCommerce email system for renewal orders so they can be enabled/disabled, and the content/templates can be customised. @@ -832,7 +864,7 @@ 2013.08.15 - version 1.3.11 - * When a subscription payment is due on the 29th or 30th day of February (i.e. it is normally charged on the 29th or 30th day of the month, and the next billing month is February) charge on the last day of February instead. More details: http://docs.woothemes.com/document/subscriptions/faq/#section-16 + * When a subscription payment is due on the 29th or 30th day of February (i.e. it is normally charged on the 29th or 30th day of the month, and the next billing month is February) charge on the last day of February instead. More details: http://docs.woocommerce.com/document/subscriptions/faq/#section-16 * Trial and subscription expiration dates now match payment dates by using the last day of the month instead of PHP's strtotime() month addition * Fix Variable Subscription prices when not all variations have a sale price or sign-up fee * Fix duplicate payment bug where a 2nd payment was charged (n - 1) hours after the first for the payment immediately following a free trial when the next payment date was changed for a subscription with a free trial that was manually added to the site on sites using a timezone of UTC -n @@ -884,8 +916,8 @@ * Fix bug applying discount coupons twice to manual renewals and renewal of a failed automatic payment 2013.06.24 - version 1.3.5 - * Coupon Behaviour Change: due to popular demand, WooCommerce's Product and Cart coupons now discount only the first payment. This also improves compatibility with the Point & Rewards and Gift Certificate extensions. More details: http://docs.woothemes.com/document/faq/#section-3 - * Add new 'WCS_DEBUG' mode to make it easier to test renewal payments. More details: http://docs.woothemes.com/document/subscriptions/faq/#section-29 + * Coupon Behaviour Change: due to popular demand, WooCommerce's Product and Cart coupons now discount only the first payment. This also improves compatibility with the Point & Rewards and Gift Certificate extensions. More details: http://docs.woocommerce.com/document/faq/#section-4 + * Add new 'WCS_DEBUG' mode to make it easier to test renewal payments. More details: https://docs.woocommerce.com/document/testing-subscription-renewal-payments/ * Add new option to limit a subscription product to one active subscription per customer * Update translation files (pot file) * Hide redundant "Sold Individually" checkbox on "Edit Product" screen (subscriptions can only be purchased individually) diff --git a/includes/abstracts/abstract-wcs-retry-store.php b/includes/abstracts/abstract-wcs-retry-store.php new file mode 100644 index 0000000..05d7d88 --- /dev/null +++ b/includes/abstracts/abstract-wcs-retry-store.php @@ -0,0 +1,107 @@ +get_retry_ids_for_order( $order_id ) as $retry_id ) { + $retries[ $retry_id ] = $this->get_retry( $retry_id ); + } + + return $retries; + } + + /** + * Get the details of the last retry (if any) recorded for a given order + * + * @param int $order_id + * @return WCS_Retry | null + */ + public function get_last_retry_for_order( $order_id ) { + + $retry_ids = $this->get_retry_ids_for_order( $order_id ); + + if ( ! empty( $retry_ids ) ) { + $last_retry_id = array_pop( $retry_ids ); + $last_retry = $this->get_retry( $last_retry_id ); + } else { + $last_retry = null; + } + + return $last_retry; + } + + /** + * Get the number of retries stored in the database for a given order + * + * @param int $order_id + * @return int + */ + public function get_retry_count_for_order( $order_id ) { + + $retry_post_ids = $this->get_retry_ids_for_order( $order_id ); + + return count( $retry_post_ids ); + } +} diff --git a/includes/abstracts/abstract-wcs-scheduler.php b/includes/abstracts/abstract-wcs-scheduler.php index d723484..f1f1896 100644 --- a/includes/abstracts/abstract-wcs-scheduler.php +++ b/includes/abstracts/abstract-wcs-scheduler.php @@ -35,7 +35,7 @@ abstract class WCS_Scheduler { * * @param object $subscription An instance of a WC_Subscription object * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'end', 'end_of_prepaid_term' or a custom date type - * @param string $datetime A MySQL formated date/time string in the GMT/UTC timezone. + * @param string $datetime A MySQL formatted date/time string in the GMT/UTC timezone. */ abstract public function update_date( $subscription, $date_type, $datetime ); @@ -51,8 +51,8 @@ abstract class WCS_Scheduler { * When a subscription's status is updated, maybe schedule an event * * @param object $subscription An instance of a WC_Subscription object - * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'end', 'end_of_prepaid_term' or a custom date type - * @param string $datetime A MySQL formated date/time string in the GMT/UTC timezone. + * @param string $new_status A valid subscription status + * @param string $old_status A valid subscription status */ abstract public function update_status( $subscription, $new_status, $old_status ); } diff --git a/includes/admin/class-wc-subscriptions-admin.php b/includes/admin/class-wc-subscriptions-admin.php index 9ee7158..fd1d799 100644 --- a/includes/admin/class-wc-subscriptions-admin.php +++ b/includes/admin/class-wc-subscriptions-admin.php @@ -57,9 +57,6 @@ class WC_Subscriptions_Admin { // Add subscription shipping options on edit product page add_action( 'woocommerce_product_options_shipping', __CLASS__ . '::subscription_shipping_fields' ); - // Add advanced subscription options on edit product page - add_action( 'woocommerce_product_options_reviews', __CLASS__ . '::subscription_advanced_fields' ); - // And also on the variations section add_action( 'woocommerce_product_after_variable_attributes', __CLASS__ . '::variable_subscription_pricing_fields', 10, 3 ); @@ -111,6 +108,8 @@ class WC_Subscriptions_Admin { // Do not display formatted order total on the Edit Order administration screen add_filter( 'woocommerce_get_formatted_order_total', __CLASS__ . '::maybe_remove_formatted_order_total_filter', 0, 2 ); + + add_action( 'woocommerce_payment_gateways_settings', __CLASS__ . '::add_recurring_payment_gateway_information', 10 , 1 ); } /** @@ -122,8 +121,8 @@ class WC_Subscriptions_Admin { */ public static function add_subscription_products_to_select( $product_types ) { - $product_types['subscription'] = __( 'Simple Subscription', 'woocommerce-subscriptions' ); - $product_types['variable-subscription'] = __( 'Variable Subscription', 'woocommerce-subscriptions' ); + $product_types['subscription'] = __( 'Simple subscription', 'woocommerce-subscriptions' ); + $product_types['variable-subscription'] = __( 'Variable subscription', 'woocommerce-subscriptions' ); return $product_types; } @@ -136,62 +135,60 @@ class WC_Subscriptions_Admin { public static function subscription_pricing_fields() { global $post; + $chosen_price = get_post_meta( $post->ID, '_subscription_price', true ); + $chosen_interval = get_post_meta( $post->ID, '_subscription_period_interval', true ); + $chosen_trial_length = WC_Subscriptions_Product::get_trial_length( $post->ID ); + $chosen_trial_period = WC_Subscriptions_Product::get_trial_period( $post->ID ); + + $price_tooltip = __( 'Choose the subscription price, billing interval and period.', 'woocommerce-subscriptions' ); + // translators: placeholder is trial period validation message if passed an invalid value (e.g. "Trial period can not exceed 4 weeks") + $trial_tooltip = sprintf( _x( 'An optional period of time to wait before charging the first recurring payment. Any sign up fee will still be charged at the outset of the subscription. %s', 'Trial period field tooltip on Edit Product administration screen', 'woocommerce-subscriptions' ), self::get_trial_period_validation_message() ); + // Set month as the default billing period - if ( ! $subscription_period = get_post_meta( $post->ID, '_subscription_period', true ) ) { - $subscription_period = 'month'; + if ( ! $chosen_period = get_post_meta( $post->ID, '_subscription_period', true ) ) { + $chosen_period = 'month'; } echo '
'; - // Subscription Price - woocommerce_wp_text_input( array( - 'id' => '_subscription_price', - 'class' => 'wc_input_subscription_price', - // translators: placeholder is a currency symbol / code - 'label' => sprintf( __( 'Subscription Price (%s)', 'woocommerce-subscriptions' ), get_woocommerce_currency_symbol() ), - 'placeholder' => _x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ), - 'type' => 'text', - 'custom_attributes' => array( - 'step' => 'any', - 'min' => '0', - ), - ) ); - - // Subscription Period Interval - woocommerce_wp_select( array( - 'id' => '_subscription_period_interval', - 'class' => 'wc_input_subscription_period_interval', - 'label' => __( 'Subscription Periods', 'woocommerce-subscriptions' ), - 'options' => wcs_get_subscription_period_interval_strings(), - ) - ); - - // Billing Period - woocommerce_wp_select( array( - 'id' => '_subscription_period', - 'class' => 'wc_input_subscription_period', - 'label' => __( 'Billing Period', 'woocommerce-subscriptions' ), - 'value' => $subscription_period, - 'description' => _x( 'for', 'for in "Every month _for_ 12 months"', 'woocommerce-subscriptions' ), - 'options' => wcs_get_subscription_period_strings(), - ) - ); + // Subscription Price, Interval and Period + ?>

+ + + + + + + + + +

'_subscription_length', - 'class' => 'wc_input_subscription_length', - 'label' => __( 'Subscription Length', 'woocommerce-subscriptions' ), - 'options' => wcs_get_subscription_ranges( $subscription_period ), + 'class' => 'wc_input_subscription_length select short', + 'label' => __( 'Subscription length', 'woocommerce-subscriptions' ), + 'options' => wcs_get_subscription_ranges( $chosen_period ), + 'desc_tip' => true, + 'description' => __( 'Automatically expire the subscription after this length of time. This length is in addition to any free trial or amount of time provided before a synchronised first renewal date.', 'woocommerce-subscriptions' ), ) ); // Sign-up Fee woocommerce_wp_text_input( array( 'id' => '_subscription_sign_up_fee', - 'class' => 'wc_input_subscription_intial_price', + 'class' => 'wc_input_subscription_intial_price short', // translators: %s is a currency symbol / code - 'label' => sprintf( __( 'Sign-up Fee (%s)', 'woocommerce-subscriptions' ), get_woocommerce_currency_symbol() ), + 'label' => sprintf( __( 'Sign-up fee (%s)', 'woocommerce-subscriptions' ), get_woocommerce_currency_symbol() ), 'placeholder' => _x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ), 'description' => __( 'Optionally include an amount to be charged at the outset of the subscription. The sign-up fee will be charged immediately, even if the product has a free trial or the payment dates are synced.', 'woocommerce-subscriptions' ), 'desc_tip' => true, @@ -203,23 +200,19 @@ class WC_Subscriptions_Admin { ) ); // Trial Length - woocommerce_wp_text_input( array( - 'id' => '_subscription_trial_length', - 'class' => 'wc_input_subscription_trial_length', - 'label' => __( 'Free Trial', 'woocommerce-subscriptions' ), - ) ); - - // Trial Period - woocommerce_wp_select( array( - 'id' => '_subscription_trial_period', - 'class' => 'wc_input_subscription_trial_period', - 'label' => __( 'Subscription Trial Period', 'woocommerce-subscriptions' ), - 'options' => wcs_get_available_time_periods(), - // translators: placeholder is trial period validation message if passed an invalid value (e.g. "Trial period can not exceed 4 weeks") - 'description' => sprintf( _x( 'An optional period of time to wait before charging the first recurring payment. Any sign up fee will still be charged at the outset of the subscription. %s', 'Trial period dropdown\'s description in pricing fields', 'woocommerce-subscriptions' ), self::get_trial_period_validation_message() ), - 'desc_tip' => true, - 'value' => WC_Subscriptions_Product::get_trial_period( $post->ID ), // Explicitly set value in to ensure backward compatibility - ) ); + ?>

+ + + + + + + +

'_subscription_one_time_shipping', - 'label' => __( 'One Time Shipping', 'woocommerce-subscriptions' ), + 'label' => __( 'One time shipping', 'woocommerce-subscriptions' ), 'description' => __( 'Shipping for subscription products is normally charged on the initial order and all renewal orders. Enable this to only charge shipping once on the initial order. Note: for this setting to be enabled the subscription must not have a free trial or a synced renewal date.', 'woocommerce-subscriptions' ), 'desc_tip' => true, ) ); @@ -254,30 +247,11 @@ class WC_Subscriptions_Admin { /** * Output advanced subscription options on the "Edit Product" admin screen - * + * @deprecated 2.1 * @since 1.3.5 */ public static function subscription_advanced_fields() { - global $post; - - echo '
'; - echo '
'; - - // Only one Subscription per customer - woocommerce_wp_select( array( - 'id' => '_subscription_limit', - 'label' => __( 'Limit Subscription', 'woocommerce-subscriptions' ), - // translators: placeholders are opening and closing link tags - 'description' => sprintf( __( 'Only allow a customer to have one subscription to this product. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), - 'options' => array( - 'no' => __( 'Do not limit', 'woocommerce-subscriptions' ), - 'active' => __( 'Limit to one active subscription', 'woocommerce-subscriptions' ), - 'any' => __( 'Limit to one of any status', 'woocommerce-subscriptions' ), - ), - ) ); - - do_action( 'woocommerce_subscriptions_product_options_advanced' ); - + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::admin_edit_product_fields()' ); } /** @@ -318,13 +292,13 @@ class WC_Subscriptions_Admin { global $post; if ( WC_Subscriptions_Product::is_subscription( $post->ID ) ) : ?> - - - - - - - + + + + + + + id ) { wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_Subscriptions::$version ); wp_enqueue_style( 'woocommerce_subscriptions_admin', plugin_dir_url( WC_Subscriptions::$plugin_file ) . 'assets/css/admin.css', array( 'woocommerce_admin_styles' ), WC_Subscriptions::$version ); } @@ -793,7 +767,7 @@ class WC_Subscriptions_Admin { // Move Active Subscriber before Orders for aesthetics $last_column = array_slice( $columns, -1, 1, true ); array_pop( $columns ); - $columns['woocommerce_active_subscriber'] = __( 'Active Subscriber?', 'woocommerce-subscriptions' ); + $columns['woocommerce_active_subscriber'] = __( 'Active subscriber?', 'woocommerce-subscriptions' ); $columns += $last_column; } @@ -993,25 +967,6 @@ class WC_Subscriptions_Admin { $roles_options[ $role ] = translate_user_role( $details['name'] ); } - $available_gateways = array(); - - foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) { - if ( $gateway->supports( 'subscriptions' ) ) { - $available_gateways[] = sprintf( '%s [%s]', $gateway->title, $gateway->id ); - } - } - - if ( count( $available_gateways ) == 0 ) { - // translators: $1-2: opening and closing tags of a link that takes to PayPal settings, $3-4: opening and closing tags of a link that takes to Woo marketplace / Stripe product page - $available_gateways_description = sprintf( __( 'No payment gateways capable of processing automatic subscription payments are enabled. Please enable the %1$sPayPal Standard%2$s gateway or get the %3$sfree Stripe extension%4$s if you want to process automatic payments.', 'woocommerce-subscriptions' ), '', '', '', '' ); - } elseif ( count( $available_gateways ) == 1 ) { - // translators: placeholder is name of a gateway - $available_gateways_description = sprintf( __( 'The %s gateway can process automatic subscription payments.', 'woocommerce-subscriptions' ), '' . $available_gateways[0] . '' ); - } elseif ( count( $available_gateways ) > 1 ) { - // translators: %1$s - a comma separated list of gateway names (e.g. "stripe, paypal, worldpay"), %2$s - one name of gateway (e.g. "authorize.net") - $available_gateways_description = sprintf( __( 'The %1$s & %2$s gateways can process automatic subscription payments.', 'woocommerce-subscriptions' ), '' . implode( ', ', array_slice( $available_gateways, 0, count( $available_gateways ) - 1 ) ) . '', '' . array_pop( $available_gateways ) . '' ); - } - return apply_filters( 'woocommerce_subscription_settings', array( array( @@ -1093,7 +1048,7 @@ class WC_Subscriptions_Admin { 'default' => 'no', 'type' => 'checkbox', // translators: placeholders are opening and closing link tags - 'desc_tip' => sprintf( __( 'With manual renewals, a customer\'s subscription is put on-hold until they login and pay to renew it. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), + 'desc_tip' => sprintf( __( 'With manual renewals, a customer\'s subscription is put on-hold until they login and pay to renew it. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), 'checkboxgroup' => 'start', 'show_if_checked' => 'option', ), @@ -1104,7 +1059,7 @@ class WC_Subscriptions_Admin { 'default' => 'no', 'type' => 'checkbox', // translators: placeholders are opening and closing link tags - 'desc_tip' => sprintf( __( 'If you never want a customer to be automatically charged for a subscription renewal payment, you can turn off automatic payments completely. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), + 'desc_tip' => sprintf( __( 'If you never want a customer to be automatically charged for a subscription renewal payment, you can turn off automatic payments completely. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), 'checkboxgroup' => 'end', 'show_if_checked' => 'yes', ), @@ -1148,28 +1103,6 @@ class WC_Subscriptions_Admin { ), array( 'type' => 'sectionend', 'id' => self::$option_prefix . '_miscellaneous' ), - - array( - 'name' => __( 'Payment Gateways', 'woocommerce-subscriptions' ), - 'desc' => $available_gateways_description, - 'id' => self::$option_prefix . '_payment_gateways_available', - 'type' => 'informational', - ), - - array( - // translators: placeholders are opening and closing link tags - 'desc' => sprintf( __( 'Other payment gateways can be used to process %smanual subscription renewal payments%s only.', 'woocommerce-subscriptions' ), '', '' ), - 'id' => self::$option_prefix . '_payment_gateways_additional', - 'type' => 'informational', - ), - - array( - // translators: $1-$2: opening and closing tags. Link to documents->payment gateways, 3$-4$: opening and closing tags. Link to woothemes extensions shop page - 'desc' => sprintf( __( 'Find new gateways that %1$ssupport automatic subscription payments%2$s in the official %3$sWooCommerce Marketplace%4$s.', 'woocommerce-subscriptions' ), '', '', '', '' ), - 'id' => self::$option_prefix . '_payment_gateways_additional', - 'type' => 'informational', - ), - ) ); } @@ -1209,7 +1142,7 @@ class WC_Subscriptions_Admin {

- +

@@ -1511,13 +1444,64 @@ class WC_Subscriptions_Admin { } /** - * Deprecated due to new meta boxes required for WC 2.2. + * Add recurring payment gateway information after the Settings->Checkout->Payment Gateways table. + * This includes links to find additional gateways, information about manual renewals + * and a warning if no payment gateway which supports automatic recurring payments is enabled/setup correctly. * - * @deprecated 1.5.10 + * @since 2.1 */ - public static function add_related_orders_meta_box() { - _deprecated_function( __METHOD__, '1.5.10', __CLASS__ . '::add_meta_boxes()' ); - self::add_meta_boxes(); + public static function add_recurring_payment_gateway_information( $settings ) { + $available_gateways_description = ''; + + if ( ! WC_Subscriptions_Payment_Gateways::one_gateway_supports( 'subscriptions' ) ) { + // translators: $1-2: opening and closing tags of a link that takes to Woo marketplace / Stripe product page + $available_gateways_description = sprintf( __( 'No payment gateways capable of processing automatic subscription payments are enabled. If you would like to process automatic payments, we recommend the %1$sfree Stripe extension%2$s.', 'woocommerce-subscriptions' ), '', '' ); + } + + $recurring_payment_settings = array( + array( + 'name' => __( 'Recurring Payments', 'woocommerce-subscriptions' ), + 'desc' => $available_gateways_description, + 'id' => WC_Subscriptions_Admin::$option_prefix . '_payment_gateways_available', + 'type' => 'informational', + ), + + array( + // translators: placeholders are opening and closing link tags + 'desc' => sprintf( __( 'Payment gateways which don\'t support automatic recurring payments can be used to process %smanual subscription renewal payments%s.', 'woocommerce-subscriptions' ), '', '' ), + 'id' => WC_Subscriptions_Admin::$option_prefix . '_payment_gateways_additional', + 'type' => 'informational', + ), + + array( + // translators: $1-$2: opening and closing tags. Link to documents->payment gateways, 3$-4$: opening and closing tags. Link to woothemes extensions shop page + 'desc' => sprintf( __( 'Find new gateways that %1$ssupport automatic subscription payments%2$s in the official %3$sWooCommerce Marketplace%4$s.', 'woocommerce-subscriptions' ), '', '', '', '' ), + 'id' => WC_Subscriptions_Admin::$option_prefix . '_payment_gateways_additional', + 'type' => 'informational', + ), + ); + + $insert_index = array_search( array( + 'type' => 'sectionend', + 'id' => 'payment_gateways_options', + ), $settings + ); + + // reconstruct the settings array, inserting the new settings after the payment gatways table + $checkout_settings = array(); + + foreach ( $settings as $key => $value ) { + + $checkout_settings[ $key ] = $value; + unset( $settings[ $key ] ); + + if ( $key == $insert_index ) { + $checkout_settings = array_merge( $checkout_settings, $recurring_payment_settings, $settings ); + break; + } + } + + return $checkout_settings; } /** @@ -1557,23 +1541,6 @@ class WC_Subscriptions_Admin { _deprecated_function( __METHOD__, '2.0' ); } - /** - * Removes anything that's not a digit or a dot from a string. Sadly it assumes that the decimal separator is a dot. - * That however can be changed in WooCommerce settings, surfacing bugs such as 9,90 becoming 990, a hundred fold - * increase. Use wc_format_decimal instead. - * - * Left in for backward compatibility reasons. - * - * @deprecated 1.5.24 - */ - private static function clean_number( $number ) { - _deprecated_function( __METHOD__, '1.5.23', 'wc_format_decimal()' ); - - $number = preg_replace( '/[^0-9\.]/', '', $number ); - - return $number; - } - /** * Filter the "Orders" list to show only renewal orders associated with a specific parent order. * diff --git a/includes/admin/class-wcs-admin-meta-boxes.php b/includes/admin/class-wcs-admin-meta-boxes.php index 75c8afb..254a9df 100644 --- a/includes/admin/class-wcs-admin-meta-boxes.php +++ b/includes/admin/class-wcs-admin-meta-boxes.php @@ -43,6 +43,8 @@ class WCS_Admin_Meta_Boxes { add_action( 'woocommerce_order_action_wcs_create_pending_renewal', __CLASS__ . '::create_pending_renewal_action_request', 10, 1 ); add_filter( 'woocommerce_resend_order_emails_available', __CLASS__ . '::remove_order_email_actions', 0, 1 ); + + add_action( 'woocommerce_order_action_wcs_retry_renewal_payment', __CLASS__ . '::process_retry_renewal_payment_action_request', 10, 1 ); } /** @@ -111,6 +113,14 @@ class WCS_Admin_Meta_Boxes { 'payment_method' => wcs_get_subscription( $post )->payment_method, 'search_customers_nonce' => wp_create_nonce( 'search-customers' ), ) ) ); + } else if ( 'shop_order' == $screen->id ) { + + wp_enqueue_script( 'wcs-admin-meta-boxes-order', plugin_dir_url( WC_Subscriptions::$plugin_file ) . '/assets/js/admin/wcs-meta-boxes-order.js' ); + + wp_localize_script( 'wcs-admin-meta-boxes-order', 'wcs_admin_order_meta_boxes', array( + 'retry_renewal_payment_action_warning' => __( "Are you sure you want to retry payment for this renewal order?\n\nThis will attempt to charge the customer and send renewal order emails (if emails are enabled).", 'woocommerce-subscriptions' ), + ) + ); } } @@ -131,6 +141,9 @@ class WCS_Admin_Meta_Boxes { } $actions['wcs_create_pending_renewal'] = esc_html__( 'Create pending renewal order', 'woocommerce-subscriptions' ); + + } else if ( self::can_renewal_order_be_retried( $theorder ) ) { + $actions['wcs_retry_renewal_payment'] = esc_html__( 'Retry Renewal Payment', 'woocommerce-subscriptions' ); } return $actions; @@ -181,6 +194,57 @@ class WCS_Admin_Meta_Boxes { return $email_actions; } + + /** + * Process the action request to retry renewal payment for failed renewal orders. + * + * @param WC_Order $order + * @since 2.1 + */ + public static function process_retry_renewal_payment_action_request( $order ) { + + if ( self::can_renewal_order_be_retried( $order ) ) { + // init payment gateways + WC()->payment_gateways(); + + do_action( 'woocommerce_scheduled_subscription_payment_' . $order->payment_method, $order->get_total(), $order ); + } + } + + /** + * Determines if a renewal order payment can be retried. A renewal order payment can only be retried when: + * - Order is a renewal order + * - Order status is failed + * - Order payment method isn't empty + * - Order total > 0 + * - Subscription/s aren't manual + * - Subscription payment method supports date changes + * - Order payment method has_action('woocommerce_scheduled_subscription_payment_..') + * + * @param WC_Order $order + * @return bool + * @since 2.1 + */ + private static function can_renewal_order_be_retried( $order ) { + + $can_be_retried = false; + + if ( wcs_order_contains_renewal( $order ) && $order->has_status( 'failed' ) && ! empty( $order->payment_method ) && $order->get_total() > 0 ) { + + $order_payment_gateway = wc_get_payment_gateway_by_order( $order ); + $order_payment_gateway_supports = ( isset( $order_payment_gateway->id ) ) ? has_action( 'woocommerce_scheduled_subscription_payment_' . $order_payment_gateway->id ) : false; + + foreach ( wcs_get_subscriptions_for_renewal_order( $order ) as $subscription ) { + $supports_date_changes = $subscription->payment_method_supports( 'subscription_date_changes' ); + $is_automatic = ! $subscription->is_manual(); + break; + } + + $can_be_retried = $order_payment_gateway_supports && $supports_date_changes && $is_automatic; + } + + return $can_be_retried; + } } new WCS_Admin_Meta_Boxes(); diff --git a/includes/admin/class-wcs-admin-post-types.php b/includes/admin/class-wcs-admin-post-types.php index acedc38..42bd36b 100644 --- a/includes/admin/class-wcs-admin-post-types.php +++ b/includes/admin/class-wcs-admin-post-types.php @@ -73,19 +73,98 @@ class WCS_Admin_Post_Types { return $pieces; } - // we need to name ID again due to name conflict if we don't - $pieces['fields'] .= ", {$wpdb->posts}.ID AS original_id, {$wpdb->posts}.post_parent AS original_parent, CASE (SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_subscription_renewal' AND meta_value = original_id) - WHEN 0 THEN CASE (SELECT COUNT(*) FROM {$wpdb->posts} WHERE ID = original_parent) - WHEN 0 THEN 0 - ELSE (SELECT post_date_gmt FROM {$wpdb->posts} WHERE ID = original_parent) - END - ELSE (SELECT p.post_date_gmt FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '_subscription_renewal' AND meta_value = original_id ORDER BY p.post_date_gmt DESC LIMIT 1) - END - AS last_payment"; + // Let's check whether we even have the privileges to do the things we want to do + if ( $this->is_db_user_privileged() ) { + $pieces = self::posts_clauses_high_performance( $pieces ); + } else { + $pieces = self::posts_clauses_low_performance( $pieces ); + } $order = strtoupper( $query->query['order'] ); - $pieces['orderby'] = "CAST(last_payment AS DATETIME) {$order}"; + // fields and order are identical in both cases + $pieces['fields'] .= ', COALESCE(lp.last_payment, o.post_date_gmt, 0) as lp'; + $pieces['orderby'] = "CAST(lp AS DATETIME) {$order}"; + + return $pieces; + } + + /** + * Check is database user is capable of doing high performance things, such as creating temporary tables, + * indexing them, and then dropping them after. + * + * @return bool + */ + public function is_db_user_privileged() { + $permissions = $this->get_special_database_privileges(); + + return ( in_array( 'CREATE TEMPORARY TABLES', $permissions ) && in_array( 'INDEX', $permissions ) && in_array( 'DROP', $permissions ) ); + } + + /** + * Return the privileges a database user has out of CREATE TEMPORARY TABLES, INDEX and DROP. This is so we can use + * these discrete values on a debug page. + * + * @return array + */ + public function get_special_database_privileges() { + global $wpdb; + + $permissions = $wpdb->get_col( "SELECT PRIVILEGE_TYPE FROM information_schema.user_privileges WHERE GRANTEE = CONCAT( '''', REPLACE( CURRENT_USER(), '@', '''@''' ), '''' ) AND PRIVILEGE_TYPE IN ('CREATE TEMPORARY TABLES', 'INDEX', 'DROP')" ); + + return $permissions; + } + + /** + * Modifies the query for a slightly faster, yet still pretty slow query in case the user does not have + * the necessary privileges to run + * + * @param $pieces + * + * @return mixed + */ + private function posts_clauses_low_performance( $pieces ) { + global $wpdb; + + $pieces['join'] .= "LEFT JOIN + (SELECT + MAX( p.post_date_gmt ) as last_payment, + pm.meta_value + FROM {$wpdb->postmeta} pm + LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id + WHERE pm.meta_key = '_subscription_renewal' + GROUP BY pm.meta_value) lp + ON {$wpdb->posts}.ID = lp.meta_value + LEFT JOIN {$wpdb->posts} o on {$wpdb->posts}.post_parent = o.ID"; + + return $pieces; + } + + /** + * Modifies the query in such a way that makes use of the CREATE TEMPORARY TABLE, DROP and INDEX + * MySQL privileges. + * + * @param array $pieces + * + * @return array $pieces + */ + private function posts_clauses_high_performance( $pieces ) { + global $wpdb; + + // in case multiple users sort at the same time + $session = wp_get_session_token(); + + $table_name = substr( "{$wpdb->prefix}tmp_{$session}_lastpayment", 0, 64 ); + + // Let's create a temporary table, drop the previous one, because otherwise this query is hella slow + $wpdb->query( "DROP TEMPORARY TABLE IF EXISTS {$table_name}" ); + + $wpdb->query( "CREATE TEMPORARY TABLE {$table_name} (id INT, INDEX USING BTREE (id), last_payment DATETIME) AS SELECT pm.meta_value as id, MAX( p.post_date_gmt ) as last_payment FROM {$wpdb->postmeta} pm LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = '_subscription_renewal' GROUP BY pm.meta_value" ); + // Magic ends here + + $pieces['join'] .= "LEFT JOIN {$table_name} lp + ON {$wpdb->posts}.ID = lp.id + LEFT JOIN {$wpdb->posts} o on {$wpdb->posts}.post_parent = o.ID"; return $pieces; } @@ -295,6 +374,8 @@ class WCS_Admin_Post_Types { echo '

' . esc_html( $message ) . '

'; } + $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'error_count', 'marked_active' ), $_SERVER['REQUEST_URI'] ); + break; } } @@ -481,26 +562,25 @@ class WCS_Admin_Post_Types { if ( wc_product_sku_enabled() && $_product && $_product->get_sku() ) { $item_name .= $_product->get_sku() . ' - '; } - $item_name .= $item['name']; - $item_name = apply_filters( 'woocommerce_order_item_name', $item_name, $item ); - $item_name = esc_html( $item_name ); + $item_name .= apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); + $item_name = esc_html( $item_name ); + if ( $item_quantity > 1 ) { $item_name = sprintf( '%s × %s', absint( $item_quantity ), $item_name ); } if ( $_product ) { $item_name = sprintf( '%s', get_edit_post_link( $_product->id ), $item_name ); } - ob_start(); - ?> -
- array( 'href' => array() ) ) ); ?> - - [?] - -
- '; + $column_content .= wp_kses( $item_name, array( 'a' => array( 'href' => array() ) ) ); + + if ( $item_meta_html ) { + $column_content .= wcs_help_tip( $item_meta_html ); + } + + $column_content .= ''; } break; default : @@ -517,13 +597,22 @@ class WCS_Admin_Post_Types { get_sku() ) { - echo esc_html( $_product->get_sku() ) . ' - '; + $item_name .= $_product->get_sku() . ' - '; } - echo esc_html( apply_filters( 'woocommerce_order_item_name', $item['name'], $item ) ); - if ( $item_meta_html ) { ?> - [?] - + + $item_name .= apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); + $item_name = esc_html( $item_name ); + + if ( $_product ) { + $item_name = sprintf( '%s', get_edit_post_link( $_product->id ), $item_name ); + } + + echo wp_kses( $item_name, array( 'a' => array( 'href' => array() ) ) ); + if ( $item_meta_html ) { + echo wcs_help_tip( $item_meta_html ); + } ?> array( 'class' => array(), 'href' => array(), 'data-tip' => array(), 'title' => array() ), 'time' => array( 'class' => array(), 'title' => array() ), 'mark' => array( 'class' => array(), 'data-tip' => array() ), 'small' => array( 'class' => array() ), 'table' => array( 'class' => array(), 'cellspacing' => array(), 'cellpadding' => array() ), 'tr' => array( 'class' => array() ), 'td' => array( 'class' => array() ), 'div' => array( 'class' => array(), 'data-tip' => array() ), 'br' => array(), 'strong' => array(), 'span' => array( 'class' => array() ), 'p' => array( 'class' => array() ), 'button' => array( 'type' => array(), 'class' => array() ) ) ); + echo wp_kses( apply_filters( 'woocommerce_subscription_list_table_column_content', $column_content, $the_subscription, $column ), array( 'a' => array( 'class' => array(), 'href' => array(), 'data-tip' => array(), 'title' => array() ), 'time' => array( 'class' => array(), 'title' => array() ), 'mark' => array( 'class' => array(), 'data-tip' => array() ), 'small' => array( 'class' => array() ), 'table' => array( 'class' => array(), 'cellspacing' => array(), 'cellpadding' => array() ), 'tr' => array( 'class' => array() ), 'td' => array( 'class' => array() ), 'div' => array( 'class' => array(), 'data-tip' => array() ), 'br' => array(), 'strong' => array(), 'span' => array( 'class' => array(), 'data-tip' => array() ), 'p' => array( 'class' => array() ), 'button' => array( 'type' => array(), 'class' => array() ) ) ); + } /** @@ -836,7 +926,7 @@ class WCS_Admin_Post_Types { 7 => __( 'Subscription saved.', 'woocommerce-subscriptions' ), 8 => __( 'Subscription submitted.', 'woocommerce-subscriptions' ), // translators: php date string - 9 => sprintf( __( 'Subscription scheduled for: %1$s.', 'woocommerce-subscriptions' ), '' . date_i18n( _x( 'M j, Y @ G:i', 'used in "Subscription scheduled for "', 'woocommerce-subscriptions' ), strtotime( $post->post_date ) ) . '' ), + 9 => sprintf( __( 'Subscription scheduled for: %1$s.', 'woocommerce-subscriptions' ), '' . date_i18n( _x( 'M j, Y @ G:i', 'used in "Subscription scheduled for "', 'woocommerce-subscriptions' ), wcs_date_to_time( $post->post_date ) ) . '' ), 10 => __( 'Subscription draft updated.', 'woocommerce-subscriptions' ), ); diff --git a/includes/admin/class-wcs-admin-reports.php b/includes/admin/class-wcs-admin-reports.php new file mode 100644 index 0000000..124c20d --- /dev/null +++ b/includes/admin/class-wcs-admin-reports.php @@ -0,0 +1,171 @@ + Reports admin section + add_filter( 'woocommerce_admin_reports', __CLASS__ . '::initialize_reports', 12, 1 ); + + // Add the reports layout to the WooCommerce -> Reports admin section + add_filter( 'wc_admin_reports_path', __CLASS__ . '::initialize_reports_path', 12, 3 ); + + // Add any necessary scripts + add_action( 'admin_enqueue_scripts', __CLASS__ . '::reports_scripts' ); + + // Add any actions we need based on the screen + add_action( 'current_screen', __CLASS__ . '::conditional_reporting_includes' ); + + } + + /** + * Add the 'Subscriptions' report type to the WooCommerce reports screen. + * + * @param array Array of Report types & their labels, excluding the Subscription product type. + * @return array Array of Report types & their labels, including the Subscription product type. + * @since 2.1 + */ + public static function initialize_reports( $reports ) { + + $reports['subscriptions'] = array( + 'title' => __( 'Subscriptions', 'woocommerce-subscriptions' ), + 'reports' => array( + 'subscription_events_by_date' => array( + 'title' => __( 'Subscription Events by Date', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ), + 'upcoming_recurring_revenue' => array( + 'title' => __( 'Upcoming Recurring Revenue', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ), + 'retention_rate' => array( + 'title' => __( 'Retention Rate', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ), + 'subscription_by_product' => array( + 'title' => __( 'Subscriptions by Product', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ), + 'subscription_by_customer' => array( + 'title' => __( 'Subscriptions by Customer', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ), + ), + ); + + if ( WCS_Retry_Manager::is_retry_enabled() ) { + $reports['subscriptions']['reports']['subscription_payment_retry'] = array( + 'title' => __( 'Failed Payment Retries', 'woocommerce-subscriptions' ), + 'description' => '', + 'hide_title' => true, + 'callback' => array( 'WC_Admin_Reports', 'get_report' ), + ); + } + + return $reports; + } + + /** + * If we hit one of our reports in the WC get_report function, change the path to our dir. + * + * @param report_path the parth to the report. + * @param name the name of the report. + * @param class the class of the report. + * @return string path to the report template. + * @since 2.1 + */ + public static function initialize_reports_path( $report_path, $name, $class ) { + + if ( in_array( strtolower( $class ), array( 'wc_report_subscription_events_by_date', 'wc_report_upcoming_recurring_revenue', 'wc_report_retention_rate', 'wc_report_subscription_by_product', 'wc_report_subscription_by_customer', 'wc_report_subscription_payment_retry' ) ) ) { + $report_path = dirname( __FILE__ ) . '/reports/class-wcs-report-' . $name . '.php'; + } + + return $report_path; + + } + + /** + * Add any subscriptions report javascript to the admin pages. + * + * @since 1.5 + */ + public static function reports_scripts() { + global $wp_query, $post; + + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + + $screen = get_current_screen(); + $wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce-subscriptions' ) ); + + // Reports Subscriptions Pages + if ( in_array( $screen->id, apply_filters( 'woocommerce_reports_screen_ids', array( $wc_screen_id . '_page_wc-reports', 'dashboard' ) ) ) && isset( $_GET['tab'] ) && 'subscriptions' == $_GET['tab'] ) { + + wp_enqueue_script( 'wcs-reports', plugin_dir_url( WC_Subscriptions::$plugin_file ) . 'assets/js/admin/reports.js', array( 'jquery', 'jquery-ui-datepicker', 'wc-reports', 'accounting' ), WC_Subscriptions::$version ); + + // Add currency localisation params for axis label + wp_localize_script( 'wcs-reports', 'wcs_reports', array( + 'currency_format_num_decimals' => wc_get_price_decimals(), + 'currency_format_symbol' => get_woocommerce_currency_symbol(), + 'currency_format_decimal_sep' => esc_js( wc_get_price_decimal_separator() ), + 'currency_format_thousand_sep' => esc_js( wc_get_price_thousand_separator() ), + 'currency_format' => esc_js( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), get_woocommerce_price_format() ) ), // For accounting JS + ) ); + + wp_enqueue_script( 'flot-order', plugin_dir_url( WC_Subscriptions::$plugin_file ) . 'assets/js/admin/jquery.flot.orderBars' . $suffix . '.js', array( 'jquery', 'flot' ), WC_Subscriptions::$version ); + wp_enqueue_script( 'flot-axis-labels', plugin_dir_url( WC_Subscriptions::$plugin_file ) . 'assets/js/admin/jquery.flot.axislabels' . $suffix . '.js', array( 'jquery', 'flot' ), WC_Subscriptions::$version ); + } + } + + /** + * Add any reporting files we may need conditionally + * + * @since 2.1 + */ + public static function conditional_reporting_includes() { + + $screen = get_current_screen(); + + switch ( $screen->id ) { + case 'dashboard' : + include( 'reports/class-wcs-report-dashboard.php' ); + break; + } + + } +} + +new WCS_Admin_Reports(); diff --git a/includes/admin/meta-boxes/class-wcs-meta-box-payment-retries.php b/includes/admin/meta-boxes/class-wcs-meta-box-payment-retries.php new file mode 100644 index 0000000..8755a24 --- /dev/null +++ b/includes/admin/meta-boxes/class-wcs-meta-box-payment-retries.php @@ -0,0 +1,33 @@ +get_retries_for_order( $post->ID ); + + include_once( 'views/html-retries-table.php' ); + + do_action( 'woocommerce_subscriptions_retries_meta_box', $post->ID, $retries ); + } +} diff --git a/includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php b/includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php index 6a2a505..0408f22 100644 --- a/includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php +++ b/includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php @@ -77,7 +77,7 @@ class WCS_Meta_Box_Subscription_Data extends WC_Meta_Box_Order_Data {

- + '; } + /** + * Add a column to the WooCommerce -> Orders admin screen to indicate whether an order is a + * parent of a subscription, a renewal order for a subscription, or a regular order. + * + * @param array $columns The current list of columns + * @since 2.1 + */ + public static function add_contains_subscription_column( $columns ) { + + $column_header = '' . esc_attr__( 'Subscription Relationship', 'woocommerce-subscriptions' ) . ''; + + $new_columns = wcs_array_insert_after( 'shipping_address', $columns, 'subscription_relationship', $column_header ); + + return $new_columns; + } + + /** + * Add column content to the WooCommerce -> Orders admin screen to indicate whether an + * order is a parent of a subscription, a renewal order for a subscription, or a + * regular order. + * + * @param string $column The string of the current column + * @since 2.1 + */ + public static function add_contains_subscription_column_content( $column ) { + global $post; + + if ( 'subscription_relationship' == $column ) { + if ( wcs_order_contains_subscription( $post->ID, 'renewal' ) ) { + echo ''; + } elseif ( wcs_order_contains_subscription( $post->ID, 'resubscribe' ) ) { + echo ''; + } elseif ( wcs_order_contains_subscription( $post->ID, 'parent' ) ) { + echo ''; + } else { + echo ''; + } + } + } + /** * Records the initial payment against a subscription. * @@ -417,9 +467,9 @@ class WC_Subscriptions_Order { */ public static function maybe_record_subscription_payment( $order_id, $old_order_status, $new_order_status ) { - if ( wcs_order_contains_subscription( $order_id ) ) { + if ( wcs_order_contains_subscription( $order_id, 'parent' ) ) { - $subscriptions = wcs_get_subscriptions_for_order( $order_id ); + $subscriptions = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'parent' ) ); $was_activated = false; $order_completed = in_array( $new_order_status, array( apply_filters( 'woocommerce_payment_complete_order_status', 'processing', $order_id ), 'processing', 'completed' ) ) && in_array( $old_order_status, apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'on-hold', 'failed' ) ) ); @@ -441,7 +491,7 @@ class WC_Subscriptions_Order { $next_payment = $subscription->get_time( 'next_payment' ); // if either there is a free trial date or a next payment date that falls before now, we need to recalculate all the sync'd dates - if ( ( $trial_end > 0 && $trial_end < strtotime( $dates['start'] ) ) || ( $next_payment > 0 && $next_payment < strtotime( $dates['start'] ) ) ) { + if ( ( $trial_end > 0 && $trial_end < wcs_date_to_time( $dates['start'] ) ) || ( $next_payment > 0 && $next_payment < wcs_date_to_time( $dates['start'] ) ) ) { foreach ( $subscription->get_items() as $item ) { $product_id = wcs_get_canonical_product_id( $item ); @@ -626,33 +676,31 @@ class WC_Subscriptions_Order { * @since version 1.5 */ public static function restrict_manage_subscriptions() { - global $typenow, $wp_query; + global $typenow; if ( 'shop_order' != $typenow ) { return; }?> @@ -668,21 +716,51 @@ class WC_Subscriptions_Order { * @since 1.5 */ public static function orders_by_type_query( $vars ) { - global $typenow, $wp_query; + global $typenow, $wpdb; - if ( 'shop_order' == $typenow && isset( $_GET['shop_order_subtype'] ) ) { + if ( 'shop_order' == $typenow && ! empty( $_GET['shop_order_subtype'] ) ) { - if ( 'Original' == $_GET['shop_order_subtype'] ) { - $compare_operator = 'NOT EXISTS'; - } elseif ( 'Renewal' == $_GET['shop_order_subtype'] ) { - $compare_operator = 'EXISTS'; - } + if ( 'original' == $_GET['shop_order_subtype'] || 'regular' == $_GET['shop_order_subtype'] ) { + + $vars['meta_query']['relation'] = 'AND'; - if ( ! empty( $compare_operator ) ) { $vars['meta_query'][] = array( 'key' => '_subscription_renewal', - 'compare' => $compare_operator, + 'compare' => 'NOT EXISTS', ); + + $vars['meta_query'][] = array( + 'key' => '_subscription_switch', + 'compare' => 'NOT EXISTS', + ); + + } elseif ( 'parent' == $_GET['shop_order_subtype'] ) { + + $vars['post__in'] = wcs_get_subscription_orders(); + + } else { + + switch ( $_GET['shop_order_subtype'] ) { + case 'renewal' : + $meta_key = '_subscription_renewal'; + break; + case 'resubscribe' : + $meta_key = '_subscription_resubscribe'; + break; + case 'switch' : + $meta_key = '_subscription_switch'; + break; + } + + $vars['meta_query'][] = array( + 'key' => $meta_key, + 'compare' => 'EXISTS', + ); + } + + // Also exclude parent orders from non-subscription query + if ( 'regular' == $_GET['shop_order_subtype'] ) { + $vars['post__not_in'] = wcs_get_subscription_orders(); } } @@ -941,134 +1019,6 @@ class WC_Subscriptions_Order { /* Deprecated Functions */ - /** - * Returned the recurring amount for a subscription in an order. - * - * @deprecated 1.2 - * @since 1.0 - */ - public static function get_price_per_period( $order, $product_id = '' ) { - _deprecated_function( __METHOD__, '1.2', __CLASS__ . '::get_recurring_total( $order, $product_id )' ); - return self::get_recurring_total( $order, $product_id ); - } - - /** - * Creates a new order for renewing a subscription product based on the details of a previous order. - * - * @param WC_Order|int $order The WC_Order object or ID of the order for which the a new order should be created. - * @param string $product_id The ID of the subscription product in the order which needs to be added to the new order. - * @param string $new_order_role A flag to indicate whether the new order should become the master order for the subscription. Accepts either 'parent' or 'child'. Defaults to 'parent' - replace the existing order. - * @deprecated 1.2 - * @since 1.0 - */ - public static function generate_renewal_order( $original_order, $product_id, $new_order_role = 'parent' ) { - _deprecated_function( __METHOD__, '1.2', 'WC_Subscriptions_Renewal_Order::generate_renewal_order( $original_order, $product_id, array( "new_order_role" => $new_order_role ) )' ); - return WC_Subscriptions_Renewal_Order::generate_renewal_order( $original_order, $product_id, array( 'new_order_role' => $new_order_role ) ); - } - - /** - * Hooks to the renewal order created action to determine if the order should be emailed to the customer. - * - * @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. - * @deprecated 1.2 - * @since 1.0 - */ - public static function maybe_send_customer_renewal_order_email( $order ) { - _deprecated_function( __METHOD__, '1.2', 'WC_Subscriptions_Renewal_Order::maybe_send_customer_renewal_order_email( $order )' ); - WC_Subscriptions_Renewal_Order::maybe_send_customer_renewal_order_email( $order ); - } - - /** - * Processing Order - * - * @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. - * @deprecated 1.2 - * @since 1.0 - */ - public static function send_customer_renewal_order_email( $order ) { - _deprecated_function( __METHOD__, '1.2', 'WC_Subscriptions_Renewal_Order::send_customer_renewal_order_email( $order )' ); - WC_Subscriptions_Renewal_Order::send_customer_renewal_order_email( $order ); - } - - /** - * Check if a given order is a subscription renewal order - * - * @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. - * @deprecated 1.2 - * @since 1.0 - */ - public static function is_renewal( $order ) { - _deprecated_function( __METHOD__, '1.2', 'wcs_order_contains_renewal( $order )' ); - return wcs_order_contains_renewal( $order ); - } - - /** - * Once payment is completed on an order, record the payment against the subscription automatically so that - * payment gateway extension developers don't have to do this. - * - * @param int $order_id The id of the order to record payment against - * @deprecated 1.2 - * @since 1.1.2 - */ - public static function record_order_payment( $order_id ) { - _deprecated_function( __METHOD__, '1.2', __CLASS__ . '::maybe_record_order_payment( $order_id )' ); - return self::maybe_record_order_payment( $order_id ); - } - - /** - * Checks an order item to see if it is a subscription. The item needs to exist and have been a subscription - * product at the time of purchase for the function to return true. - * - * @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in. - * @param int $product_id The ID of a WC_Product object purchased in the order. - * @return bool True if the order contains a subscription, otherwise false. - * @deprecated 1.2.4 - */ - public static function is_item_a_subscription( $order, $product_id ) { - _deprecated_function( __METHOD__, '1.2.4', __CLASS__ . '::is_item_subscription( $order, $product_id )' ); - return self::is_item_subscription( $order, $product_id ); - } - - /** - * Deprecated due to change of order item ID/API in WC 2.0. - * - * @param WC_Order|int $order The WC_Order object or ID of the order for which the meta should be sought. - * @param int $item_id The product/post ID of a subscription. Option - if no product id is provided, the first item's meta will be returned - * @since 1.2 - * @deprecated 1.2.5 - */ - public static function get_item( $order, $product_id = '' ) { - _deprecated_function( __METHOD__, '1.2.5', __CLASS__ . '::get_item_by_product_id( $order, $product_id )' ); - return self::get_item_by_product_id( $order, $product_id ); - } - - /** - * Deprecated due to different totals calculation method. - * - * Determined the proportion of the order total that a recurring amount accounts for and - * returns that proportion. - * - * If there is only one subscription in the order and no sign up fee for the subscription, - * this function will return 1 (i.e. 100%). - * - * Shipping only applies to recurring amounts so is deducted from both the order total and - * recurring amount so it does not distort the proportion. - * - * @param WC_Order|int $order A WC_Order object or ID of a WC_Order order. - * @return float The proportion of the order total which the recurring amount accounts for - * @since 1.2 - * @deprecated 1.4 - */ - public static function get_recurring_total_proportion( $order, $product_id = '' ) { - _deprecated_function( __METHOD__, '1.4' ); - - $order_shipping_total = self::get_recurring_shipping_total( $order ) + self::get_recurring_shipping_tax_total( $order ); - $order_total_sans_shipping = $order->get_total() - $order_shipping_total; - $recurring_total_sans_shipping = self::get_recurring_total( $order, $product_id ) - $order_shipping_total; - - return $recurring_total_sans_shipping / $order_total_sans_shipping; - } - /** * Checks an order to see if it contains a subscription. * @@ -1835,7 +1785,7 @@ class WC_Subscriptions_Order { $next_payment = $subscription->calculate_date( 'next_payment' ); } - $next_payment = ( 'mysql' == $type && 0 != $next_payment ) ? $next_payment : strtotime( $next_payment ); + $next_payment = ( 'mysql' == $type && 0 != $next_payment ) ? $next_payment : wcs_date_to_time( $next_payment ); return apply_filters( 'woocommerce_subscriptions_calculated_next_payment_date', $next_payment, $order, $product_id, $type, $from_date, $from_date ); } diff --git a/includes/class-wc-subscriptions-product.php b/includes/class-wc-subscriptions-product.php index b44ab5b..a0f6301 100644 --- a/includes/class-wc-subscriptions-product.php +++ b/includes/class-wc-subscriptions-product.php @@ -15,9 +15,6 @@ class WC_Subscriptions_Product { /* cache the check on whether the session has an order awaiting payment for a given product */ protected static $order_awaiting_payment_for_product = array(); - /* cache whether a given product is purchasable or not to save running lots of queries for the same product in the same request */ - protected static $is_purchasable_cache = array(); - protected static $subscription_meta_fields = array( '_subscription_price', '_subscription_sign_up_fee', @@ -587,7 +584,7 @@ class WC_Subscriptions_Product { $first_renewal_timestamp = self::get_first_renewal_payment_time( $product_id, $from_date, $timezone ); if ( $first_renewal_timestamp > 0 ) { - $first_renewal_date = date( 'Y-m-d H:i:s', $first_renewal_timestamp ); + $first_renewal_date = gmdate( 'Y-m-d H:i:s', $first_renewal_timestamp ); } else { $first_renewal_date = 0; } @@ -626,18 +623,11 @@ class WC_Subscriptions_Product { // If the subscription has a free trial period, the first renewal is the same as the expiration of the free trial if ( $trial_length > 0 ) { - $first_renewal_timestamp = strtotime( self::get_trial_expiration_date( $product_id, $from_date ) ); + $first_renewal_timestamp = wcs_date_to_time( self::get_trial_expiration_date( $product_id, $from_date ) ); } else { - $from_timestamp = strtotime( $from_date ); - $billing_period = self::get_period( $product_id ); - - if ( 'month' == $billing_period ) { - $first_renewal_timestamp = wcs_add_months( $from_timestamp, $billing_interval ); - } else { - $first_renewal_timestamp = strtotime( "+ $billing_interval {$billing_period}s", $from_timestamp ); - } + $first_renewal_timestamp = wcs_add_time( $billing_interval, self::get_period( $product_id ), wcs_date_to_time( $from_date ) ); if ( 'site' == $timezone ) { $first_renewal_timestamp += ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); @@ -672,7 +662,7 @@ class WC_Subscriptions_Product { $from_date = self::get_trial_expiration_date( $product_id, $from_date ); } - $expiration_date = gmdate( 'Y-m-d H:i:s', wcs_add_time( $subscription_length, self::get_period( $product_id ), strtotime( $from_date ) ) ); + $expiration_date = gmdate( 'Y-m-d H:i:s', wcs_add_time( $subscription_length, self::get_period( $product_id ), wcs_date_to_time( $from_date ) ) ); } else { @@ -694,7 +684,6 @@ class WC_Subscriptions_Product { */ public static function get_trial_expiration_date( $product_id, $from_date = '' ) { - $trial_period = self::get_trial_period( $product_id ); $trial_length = self::get_trial_length( $product_id ); if ( $trial_length > 0 ) { @@ -703,11 +692,8 @@ class WC_Subscriptions_Product { $from_date = gmdate( 'Y-m-d H:i:s' ); } - if ( 'month' == $trial_period ) { - $trial_expiration_date = date( 'Y-m-d H:i:s', wcs_add_months( strtotime( $from_date ), $trial_length ) ); - } else { // Safe to just add the billing periods - $trial_expiration_date = date( 'Y-m-d H:i:s', strtotime( "+ {$trial_length} {$trial_period}s", strtotime( $from_date ) ) ); - } + $trial_expiration_date = gmdate( 'Y-m-d H:i:s', wcs_add_time( $trial_length, self::get_trial_period( $product_id ), wcs_date_to_time( $from_date ) ) ); + } else { $trial_expiration_date = 0; @@ -903,31 +889,6 @@ class WC_Subscriptions_Product { } } - /** - * If a product is being marked as not purchasable because it is limited and the customer has a subscription, - * but the current request is to resubscribe to the subscription, then mark it as purchasable. - * - * @since 2.0 - * @return bool - */ - public static function is_purchasable( $is_purchasable, $product ) { - global $wp; - - if ( ! isset( self::$is_purchasable_cache[ $product->id ] ) ) { - - self::$is_purchasable_cache[ $product->id ] = $is_purchasable; - - if ( self::is_subscription( $product->id ) && 'no' != $product->limit_subscriptions && ! wcs_is_order_received_page() && ! wcs_is_paypal_api_page() ) { - - if ( ( ( 'active' == $product->limit_subscriptions && wcs_user_has_subscription( 0, $product->id, 'on-hold' ) ) || wcs_user_has_subscription( 0, $product->id, $product->limit_subscriptions ) ) && ! self::order_awaiting_payment_for_product( $product->id ) ) { - self::$is_purchasable_cache[ $product->id ] = false; - } - } - } - - return self::$is_purchasable_cache[ $product->id ]; - } - /** * Save variation meta data when it is bulk edited from the Edit Product screen * @@ -983,50 +944,6 @@ class WC_Subscriptions_Product { } } - /** - * Check if the current session has an order awaiting payment for a subscription to a specific product line item. - * - * @return 2.0.13 - * @return bool - **/ - protected static function order_awaiting_payment_for_product( $product_id ) { - global $wp; - - if ( ! isset( self::$order_awaiting_payment_for_product[ $product_id ] ) ) { - - self::$order_awaiting_payment_for_product[ $product_id ] = false; - - if ( ! empty( WC()->session->order_awaiting_payment ) || isset( $_GET['pay_for_order'] ) ) { - - $order_id = ! empty( WC()->session->order_awaiting_payment ) ? WC()->session->order_awaiting_payment : $wp->query_vars['order-pay']; - $order = wc_get_order( absint( $order_id ) ); - - if ( is_object( $order ) && $order->has_status( array( 'pending', 'failed' ) ) ) { - foreach ( $order->get_items() as $item ) { - if ( $item['product_id'] == $product_id || $item['variation_id'] == $product_id ) { - - $subscriptions = wcs_get_subscriptions( array( - 'order_id' => $order->id, - 'product_id' => $product_id, - ) ); - - if ( ! empty( $subscriptions ) ) { - $subscription = array_pop( $subscriptions ); - - if ( $subscription->has_status( array( 'pending', 'on-hold' ) ) ) { - self::$order_awaiting_payment_for_product[ $product_id ] = true; - } - } - break; - } - } - } - } - } - - return self::$order_awaiting_payment_for_product[ $product_id ]; - } - /** * Processes an AJAX request to check if a product has a variation which is either sync'd or has a trial. * Once at least one variation with a trial or sync date is found, this will terminate and return true, otherwise false. @@ -1092,87 +1009,61 @@ class WC_Subscriptions_Product { } /** - * Calculates a price (could be per period price or sign-up fee) for a subscription less tax - * if the subscription is taxable and the prices in the store include tax. + * If a product is being marked as not purchasable because it is limited and the customer has a subscription, + * but the current request is to resubscribe to the subscription, then mark it as purchasable. * - * Based on the WC_Product::get_price_excluding_tax() function. - * - * @param float $price The price to adjust based on taxes - * @param WC_Product $product The product the price belongs too (needed to determine tax class) - * @since 1.0 + * @since 2.0 + * @return bool */ - public static function calculate_tax_for_subscription( $price, $product, $deduct_base_taxes = false ) { - _deprecated_function( __METHOD__, '1.5.8', 'WC_Product::get_price_including_tax()' ); + public static function is_purchasable( $is_purchasable, $product ) { + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::is_purchasable_product' ); + return WCS_Limiter::is_purchasable_product( $is_purchasable, $product ); + } - if ( $product->is_taxable() ) { + /** + * Check if the current session has an order awaiting payment for a subscription to a specific product line item. + * + * @return 2.0.13 + * @return bool + **/ + protected static function order_awaiting_payment_for_product( $product_id ) { + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::order_awaiting_payment_for_product' ); - $tax = new WC_Tax(); + global $wp; - $base_tax_rates = $tax->get_shop_base_rate( $product->tax_class ); - $tax_rates = $tax->get_rates( $product->get_tax_class() ); // This will get the base rate unless we're on the checkout page + if ( ! isset( self::$order_awaiting_payment_for_product[ $product_id ] ) ) { - if ( $deduct_base_taxes && wc_prices_include_tax() ) { + self::$order_awaiting_payment_for_product[ $product_id ] = false; - $base_taxes = $tax->calc_tax( $price, $base_tax_rates, true ); - $taxes = $tax->calc_tax( $price - array_sum( $base_taxes ), $tax_rates, false ); + if ( ! empty( WC()->session->order_awaiting_payment ) || isset( $_GET['pay_for_order'] ) ) { - } elseif ( get_option( 'woocommerce_prices_include_tax' ) == 'yes' ) { + $order_id = ! empty( WC()->session->order_awaiting_payment ) ? WC()->session->order_awaiting_payment : $wp->query_vars['order-pay']; + $order = wc_get_order( absint( $order_id ) ); - $taxes = $tax->calc_tax( $price, $base_tax_rates, true ); + if ( is_object( $order ) && $order->has_status( array( 'pending', 'failed' ) ) ) { + foreach ( $order->get_items() as $item ) { + if ( $item['product_id'] == $product_id || $item['variation_id'] == $product_id ) { - } else { + $subscriptions = wcs_get_subscriptions( array( + 'order_id' => $order->id, + 'product_id' => $product_id, + ) ); - $taxes = $tax->calc_tax( $price, $base_tax_rates, false ); + if ( ! empty( $subscriptions ) ) { + $subscription = array_pop( $subscriptions ); + if ( $subscription->has_status( array( 'pending', 'on-hold' ) ) ) { + self::$order_awaiting_payment_for_product[ $product_id ] = true; + } + } + break; + } + } + } } - - $tax_amount = $tax->get_tax_total( $taxes ); - - } else { - - $tax_amount = 0; - } - return $tax_amount; - } - - - /** - * Deprecated in favour of native get_price_html() method on the Subscription Product classes (e.g. WC_Product_Subscription) - * - * Output subscription string as the price html - * - * @since 1.0 - * @deprecated 1.5.18 - */ - public static function get_price_html( $price, $product ) { - _deprecated_function( __METHOD__, '1.5.18', __CLASS__ . '::get_price_string()' ); - - if ( self::is_subscription( $product ) ) { - $price = self::get_price_string( $product, array( 'price' => $price ) ); - } - - return $price; - } - - /** - * Deprecated in favour of native get_price_html() method on the Subscription Product classes (e.g. WC_Product_Subscription) - * - * Set the subscription string for products which have a $0 recurring fee, but a sign-up fee - * - * @since 1.3.4 - * @deprecated 1.5.18 - */ - public static function get_free_price_html( $price, $product ) { - _deprecated_function( __METHOD__, '1.5.18', __CLASS__ . '::get_price_string()' ); - - // Check if it has a sign-up fee (we already know it has no recurring fee) - if ( self::is_subscription( $product ) && self::get_sign_up_fee( $product ) > 0 ) { - $price = self::get_price_string( $product, array( 'price' => $price ) ); - } - - return $price; + return self::$order_awaiting_payment_for_product[ $product_id ]; } } diff --git a/includes/class-wc-subscriptions-renewal-order.php b/includes/class-wc-subscriptions-renewal-order.php index 5eec309..14ed2de 100644 --- a/includes/class-wc-subscriptions-renewal-order.php +++ b/includes/class-wc-subscriptions-renewal-order.php @@ -191,108 +191,6 @@ class WC_Subscriptions_Renewal_Order { /* Deprecated functions */ - /** - * Hooks to the renewal order created action to determine if the order should be emailed to the customer. - * - * @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. - * @since 1.2 - * @deprecated 1.4 - */ - public static function maybe_send_customer_renewal_order_email( $order ) { - _deprecated_function( __METHOD__, '1.4' ); - if ( 'yes' == get_option( WC_Subscriptions_Admin::$option_prefix . '_email_renewal_order' ) ) { - self::send_customer_renewal_order_email( $order ); - } - } - - /** - * Processing Order - * - * @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. - * @since 1.2 - * @deprecated 1.4 - */ - public static function send_customer_renewal_order_email( $order ) { - _deprecated_function( __METHOD__, '1.4' ); - - if ( ! is_object( $order ) ) { - $order = new WC_Order( $order ); - } - - $mailer = WC()->mailer(); - $mails = $mailer->get_emails(); - - $mails['WCS_Email_Customer_Renewal_Invoice']->trigger( $order->id ); - } - - /** - * Change the email subject of the new order email to specify the order is a subscription renewal order - * - * @param string $subject The default WooCommerce email subject - * @param WC_Order $order The WC_Order object which the email relates to - * @since 1.2 - * @deprecated 1.4 - */ - public static function email_subject_new_renewal_order( $subject, $order ) { - _deprecated_function( __METHOD__, '1.4' ); - - if ( wcs_order_contains_renewal( $order ) ) { - $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - // translators: 1$: blog name, 2$: order number - $subject = apply_filters( 'woocommerce_subscriptions_email_subject_new_renewal_order', sprintf( _x( '[%1$s] New Subscription Renewal Order (%2$s)', 'used in new renewal order email, deprecated', 'woocommerce-subscriptions' ), $blogname, $order->get_order_number() ), $order ); - } - - return $subject; - } - - /** - * Change the email subject of the processing order email to specify the order is a subscription renewal order - * - * @param string $subject The default WooCommerce email subject - * @param WC_Order $order The WC_Order object which the email relates to - * @since 1.2 - * @deprecated 1.4 - */ - public static function email_subject_customer_procesing_renewal_order( $subject, $order ) { - _deprecated_function( __METHOD__, '1.4' ); - - if ( wcs_order_contains_renewal( $order ) ) { - $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - $subject = apply_filters( - 'woocommerce_subscriptions_email_subject_customer_procesing_renewal_order', - // translators: placeholder is blog name - sprintf( _x( '[%s] Subscription Renewal Order', 'used as email subject for renewal order notification email to customer', 'woocommerce-subscriptions' ), $blogname ), - $order - ); - } - - return $subject; - } - - /** - * Change the email subject of the completed order email to specify the order is a subscription renewal order - * - * @param string $subject The default WooCommerce email subject - * @param WC_Order $order The WC_Order object which the email relates to - * @since 1.2 - * @deprecated 1.4 - */ - public static function email_subject_customer_completed_renewal_order( $subject, $order ) { - _deprecated_function( __METHOD__, '1.4' ); - - if ( wcs_order_contains_renewal( $order ) ) { - $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - $subject = apply_filters( - 'woocommerce_subscriptions_email_subject_customer_completed_renewal_order', - // translators: placeholder is blog name - sprintf( _x( '[%s] Subscription Renewal Order', 'used as email subject for renewal order notification email to customer', 'woocommerce-subscriptions' ), $blogname ), - $order - ); - } - - return $subject; - } - /** * Generate an order to record an automatic subscription payment. * diff --git a/includes/class-wc-subscriptions-switcher.php b/includes/class-wc-subscriptions-switcher.php index 1f22d6e..e138612 100644 --- a/includes/class-wc-subscriptions-switcher.php +++ b/includes/class-wc-subscriptions-switcher.php @@ -10,9 +10,6 @@ */ class WC_Subscriptions_Switcher { - /* cache whether a given product is purchasable or not to save running lots of queries for the same product in the same request */ - protected static $is_purchasable_cache = array(); - /** * Bootstraps the class and hooks required actions & filters. * @@ -63,10 +60,6 @@ class WC_Subscriptions_Switcher { // Don't display free trials when switching a subscription, because no free trials are provided add_filter( 'woocommerce_subscriptions_product_price_string_inclusions', __CLASS__ . '::customise_product_string_inclusions', 12, 2 ); - // Allow switching between variations on a limited subscription - add_filter( 'woocommerce_subscription_is_purchasable', __CLASS__ . '::is_purchasable', 12, 2 ); - add_filter( 'woocommerce_subscription_variation_is_purchasable', __CLASS__ . '::is_purchasable', 12, 2 ); - // Autocomplete subscription switch orders add_action( 'woocommerce_payment_complete_order_status', __CLASS__ . '::subscription_switch_autocomplete', 10, 2 ); @@ -101,12 +94,15 @@ class WC_Subscriptions_Switcher { // Display/indicate whether a cart switch item is a upgrade/downgrade/crossgrade add_filter( 'woocommerce_cart_item_subtotal', __CLASS__ . '::add_cart_item_switch_direction', 10, 3 ); - // Check if the new order was to record a switch request and maybe call a "switch completed" action. - add_action( 'subscriptions_created_for_order', __CLASS__ . '::maybe_add_switched_callback', 10, 1 ); + // Check if the order was to record a switch request and maybe call a "switch completed" action. + add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::maybe_add_switched_callback', 10, 1 ); // Revoke download permissions from old switch item add_action( 'woocommerce_subscriptions_switched_item', __CLASS__ . '::remove_download_permissions_after_switch', 10, 3 ); + // Process subscription switch changes on completed switch orders status + add_action( 'woocommerce_order_status_changed', __CLASS__ . '::process_subscription_switches', 10, 3 ); + // Check if we need to force payment on this switch, just after calculating the prorated totals in @see self::calculate_prorated_totals() add_filter( 'woocommerce_subscriptions_calculated_total', __CLASS__ . '::set_force_payment_flag_in_cart', 10, 1 ); @@ -114,7 +110,10 @@ class WC_Subscriptions_Switcher { add_filter( 'woocommerce_cart_needs_payment', __CLASS__ . '::cart_needs_payment' , 50, 2 ); // Require payment when switching from a $0 / period subscription to a non-zero subscription to process automatic payments - add_filter( 'woocommerce_payment_successful_result', __CLASS__ . '::maybe_set_payment_method' , 10, 2 ); + add_filter( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::maybe_set_payment_method_after_switch' , 10, 1 ); + + // Do not reduce product stock when the order item is simply to record a switch + add_filter( 'woocommerce_order_item_quantity', __CLASS__ . '::maybe_do_not_reduce_stock', 10, 3 ); // Mock a free trial on the cart item to make sure the switch total doesn't include any recurring amount add_filter( 'woocommerce_before_calculate_totals', __CLASS__ . '::maybe_set_free_trial', 100, 1 ); @@ -183,80 +182,71 @@ class WC_Subscriptions_Switcher { } } elseif ( is_product() && $product = wc_get_product( $post ) ) { // Automatically initiate the switch process for limited variable subscriptions - if ( wcs_is_product_switchable_type( $product ) && 'no' != $product->limit_subscriptions ) { + $limited_switchable_products = array(); - // Check if the user has an active subscription for this product, and if so, initiate the switch process - $subscriptions = wcs_get_users_subscriptions(); + if ( $product->is_type( 'grouped' ) ) { // If we're on a grouped product's page, we need to check if this grouped product has children which are limited and may need to be switched $child_ids = $product->get_children(); - foreach ( $subscriptions as $subscription ) { + foreach ( $child_ids as $child_id ) { + $product = wc_get_product( $child_id ); - // If we're on a grouped product's page, we need to check if the subscription has a child of this grouped product that needs to be switched - $subscription_product_id = false; - - if ( $product->is_type( 'grouped' ) ) { - foreach ( $child_ids as $child_id ) { - if ( $subscription->has_product( $child_id ) ) { - $subscription_product_id = $child_id; - break; - } - } + if ( 'no' != wcs_get_product_limitation( $product ) && wcs_is_product_switchable_type( $product ) ) { + $limited_switchable_products[] = $product; } + } + } elseif ( 'no' != wcs_get_product_limitation( $product ) && wcs_is_product_switchable_type( $product ) ) { + // If we're on a limited variation or single product within a group which is switchable + // we only need to look for if the customer is subscribed to this product + $limited_switchable_products[] = $product; + } - if ( $subscription->has_product( $product->id ) || $subscription_product_id ) { + // If we have limited switchable products, check if the customer is already subscribed and needs to be switched + if ( ! empty( $limited_switchable_products ) ) { - // For grouped products, we need to check the child products limitations, not the grouped product's (which will have no limitation) - if ( $subscription_product_id ) { - $child_product = wc_get_product( $subscription_product_id ); - $limitation = $child_product->limit_subscriptions; - } else { - $limitation = $product->limit_subscriptions; + $subscriptions = wcs_get_users_subscriptions(); + + foreach ( $subscriptions as $subscription ) { + foreach ( $limited_switchable_products as $product ) { + + if ( ! $subscription->has_product( $product->id ) ) { + continue; } - // If the product is limited + $limitation = wcs_get_product_limitation( $product ); + if ( 'any' == $limitation || $subscription->has_status( $limitation ) ) { $subscribed_notice = __( 'You have already subscribed to this product and it is limited to one per customer. You can not purchase the product again.', 'woocommerce-subscriptions' ); - // If switching is enabled for this product type, initiate the auto-switch process - if ( wcs_is_product_switchable_type( $product ) ) { + // Don't initiate auto-switching when the subscription requires payment + if ( $subscription->needs_payment() ) { - // Don't initiate auto-switching when the subscription requires payment - if ( $subscription->needs_payment() ) { + $last_order = $subscription->get_last_order( 'all' ); - $last_order = $subscription->get_last_order( 'all' ); - - if ( $last_order->needs_payment() ) { - // translators: 1$: is the "You have already subscribed to this product" notice, 2$-4$: opening/closing link tags, 3$: an order number - $subscribed_notice = sprintf( __( '%1$s Complete payment on %2$sOrder %3$s%4$s to be able to change your subscription.', 'woocommerce-subscriptions' ), $subscribed_notice, sprintf( '', $last_order->get_checkout_payment_url() ), $last_order->get_order_number(), '' ); - } - - WC_Subscriptions::add_notice( $subscribed_notice, 'notice' ); - break; - - } else { - - $product_id = ( $subscription_product_id ) ? $subscription_product_id : $product->id; - - // Get the matching item - foreach ( $subscription->get_items() as $line_item_id => $line_item ) { - if ( $line_item['product_id'] == $product_id || $line_item['variation_id'] == $product_id ) { - $item_id = $line_item_id; - $item = $line_item; - break; - } - } - - if ( self::can_item_be_switched_by_user( $item, $subscription ) ) { - wp_redirect( add_query_arg( 'auto-switch', 'true', self::get_switch_url( $item_id, $item, $subscription ) ) ); - exit; - } + if ( $last_order->needs_payment() ) { + // translators: 1$: is the "You have already subscribed to this product" notice, 2$-4$: opening/closing link tags, 3$: an order number + $subscribed_notice = sprintf( __( '%1$s Complete payment on %2$sOrder %3$s%4$s to be able to change your subscription.', 'woocommerce-subscriptions' ), $subscribed_notice, sprintf( '', $last_order->get_checkout_payment_url() ), $last_order->get_order_number(), '' ); } - } else { WC_Subscriptions::add_notice( $subscribed_notice, 'notice' ); break; + + } else { + + // Get the matching item + foreach ( $subscription->get_items() as $line_item_id => $line_item ) { + if ( $line_item['product_id'] == $product->id || $line_item['variation_id'] == $product->id ) { + $item_id = $line_item_id; + $item = $line_item; + break; + } + } + + if ( self::can_item_be_switched_by_user( $item, $subscription ) ) { + wp_redirect( add_query_arg( 'auto-switch', 'true', self::get_switch_url( $item_id, $item, $subscription ) ) ); + exit; + } } } } @@ -318,7 +308,7 @@ class WC_Subscriptions_Switcher { 'name' => __( 'Switching', 'woocommerce-subscriptions' ), 'type' => 'title', // translators: placeholders are opening and closing link tags - 'desc' => sprintf( __( 'Allow subscribers to switch (upgrade or downgrade) between different subscriptions. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), + 'desc' => sprintf( __( 'Allow subscribers to switch (upgrade or downgrade) between different subscriptions. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), 'id' => WC_Subscriptions_Admin::$option_prefix . '_switch_settings', ), @@ -441,15 +431,21 @@ class WC_Subscriptions_Switcher { } $product = wc_get_product( $item['product_id'] ); + $additional_query_args = array(); // Grouped product if ( 0 !== $product->post->post_parent ) { $switch_url = get_permalink( $product->post->post_parent ); } else { $switch_url = get_permalink( $product->id ); + + if ( ! empty( $_GET ) && is_product() ) { + $product_variations = $product->get_variation_attributes(); + $additional_query_args = array_intersect_key( $_GET, $product_variations ); + } } - $switch_url = self::add_switch_query_args( $subscription->id, $item_id, $switch_url ); + $switch_url = self::add_switch_query_args( $subscription->id, $item_id, $switch_url, $additional_query_args ); return apply_filters( 'woocommerce_subscriptions_switch_url', $switch_url, $item_id, $item, $subscription ); } @@ -460,12 +456,14 @@ class WC_Subscriptions_Switcher { * @param int $subscription_id A subscription's post ID * @param int $item_id The order item ID of a subscription line item * @param string $permalink The permalink of the product + * @param array $additional_query_args (optional) Additional query args to add to the switch URL * @since 2.0 */ - protected static function add_switch_query_args( $subscription_id, $item_id, $permalink ) { + protected static function add_switch_query_args( $subscription_id, $item_id, $permalink, $additional_query_args = array() ) { // manually add a nonce because we can't use wp_nonce_url() (it would escape the URL) - $permalink = add_query_arg( array( 'switch-subscription' => absint( $subscription_id ), 'item' => absint( $item_id ), '_wcsnonce' => wp_create_nonce( 'wcs_switch_request' ) ), $permalink ); + $query_args = array_merge( $additional_query_args, array( 'switch-subscription' => absint( $subscription_id ), 'item' => absint( $item_id ), '_wcsnonce' => wp_create_nonce( 'wcs_switch_request' ) ) ); + $permalink = add_query_arg( $query_args, $permalink ); return apply_filters( 'woocommerce_subscriptions_add_switch_query_args', $permalink, $subscription_id, $item_id ); } @@ -476,7 +474,7 @@ class WC_Subscriptions_Switcher { * For an item to be switchable, switching must be enabled, and the item must be for a variable subscription or * part of a grouped product (at the time the check is made, not at the time the subscription was purchased) * - * The subscription must also be active or on-hold and use manual renewals or use a payment method which supports cancellation. + * The subscription must also be active and use manual renewals or use a payment method which supports cancellation. * * @param array $item An order item on the subscription * @param WC_Subscription $subscription An instance of WC_Subscription @@ -546,6 +544,9 @@ class WC_Subscriptions_Switcher { */ public static function add_order_meta( $order_id, $posted ) { + // delete all the existing subscription switch links before adding new ones + delete_post_meta( $order_id, '_subscription_switch' ); + $switches = self::cart_contains_switches(); if ( false !== $switches ) { @@ -614,7 +615,9 @@ class WC_Subscriptions_Switcher { return; } - $order = wc_get_order( $order_id ); + $order = wc_get_order( $order_id ); + $order_items = $order->get_items(); + $switch_order_data = array(); try { // Start transaction if available @@ -642,6 +645,11 @@ class WC_Subscriptions_Switcher { $is_different_billing_schedule = false; } + // If we haven't calculated a first payment date, fall back to the recurring cart's next payment date + if ( 0 == $cart_item['subscription_switch']['first_payment_timestamp'] ) { + $cart_item['subscription_switch']['first_payment_timestamp'] = strtotime( $recurring_cart->next_payment_date ); + } + if ( 0 !== $cart_item['subscription_switch']['first_payment_timestamp'] && $next_payment_timestamp !== $cart_item['subscription_switch']['first_payment_timestamp'] ) { $is_different_payment_date = true; } elseif ( 0 !== $cart_item['subscription_switch']['first_payment_timestamp'] && 0 == $subscription->get_time( 'next_payment' ) ) { // if the subscription doesn't have a next payment but the switched item does @@ -650,7 +658,7 @@ class WC_Subscriptions_Switcher { $is_different_payment_date = false; } - if ( date( 'Y-m-d', strtotime( $recurring_cart->end_date ) ) !== date( 'Y-m-d', $subscription->get_time( 'end' ) ) ) { + if ( gmdate( 'Y-m-d', wcs_date_to_time( $recurring_cart->end_date ) ) !== gmdate( 'Y-m-d', $subscription->get_time( 'end' ) ) ) { $is_different_length = true; } else { $is_different_length = false; @@ -663,11 +671,34 @@ class WC_Subscriptions_Switcher { $is_single_item_subscription = false; } + $order_item_id = ''; + + foreach ( $order_items as $item_id => $item ) { + if ( wcs_get_canonical_product_id( $item ) == wcs_get_canonical_product_id( $cart_item ) && ( empty( $switch_order_data['switches'] ) || ! in_array( $item_id, array_keys( $switch_order_data['switches'] ) ) ) ) { + $order_item_id = $item_id; + $switch_order_data[ $subscription->id ]['switches'][ $item_id ]['subscription_item_id'] = $cart_item['subscription_switch']['item_id']; + break; + } + } + // If the item is on the same schedule, we can just add it to the new subscription and remove the old item if ( $is_single_item_subscription || ( false === $is_different_billing_schedule && false === $is_different_payment_date && false === $is_different_length ) ) { // Add the new item - $item_id = WC_Subscriptions_Checkout::add_cart_item( $subscription, $cart_item, $cart_item_key ); + $item_id = WC_Subscriptions_Checkout::add_cart_item( $subscription, $cart_item, $cart_item_key ); + $item_meta = wc_get_order_item_meta( $item_id, '' ); + + // We can't use the prorated order item price upon successful payment so store the cart price + $switch_order_data[ $subscription->id ]['switches'][ $order_item_id ]['add_order_item_data'] = array( + 'totals' => array( + 'subtotal' => $cart_item['line_subtotal'], + 'subtotal_tax' => $cart_item['line_subtotal_tax'], + 'total' => $cart_item['line_total'], + 'tax' => $cart_item['line_tax'], + 'tax_data' => $cart_item['line_tax_data'], + ), + 'meta' => $item_meta, + ); // Remove the item from the cart so that WC_Subscriptions_Checkout doesn't add it to a subscription if ( 1 == count( WC()->cart->recurring_carts[ $recurring_cart_key ]->get_cart() ) ) { @@ -676,8 +707,6 @@ class WC_Subscriptions_Switcher { } else { unset( WC()->cart->recurring_carts[ $recurring_cart_key ]->cart_contents[ $cart_item_key ] ); } - - do_action( 'woocommerce_subscription_item_switched', $order, $subscription, $item_id, $cart_item['subscription_switch']['item_id'] ); } // If the old subscription has just one item, we can safely update its billing schedule @@ -686,14 +715,18 @@ class WC_Subscriptions_Switcher { if ( $is_different_billing_schedule ) { update_post_meta( $subscription->id, '_billing_period', $cart_item['data']->subscription_period ); update_post_meta( $subscription->id, '_billing_interval', absint( $cart_item['data']->subscription_period_interval ) ); + + $switch_order_data[ $subscription->id ]['billing_schedule']['_billing_period'] = $cart_item['data']->subscription_period; + $switch_order_data[ $subscription->id ]['billing_schedule']['_billing_interval'] = absint( $cart_item['data']->subscription_period_interval ); } $updated_dates = array(); - if ( '1' == $cart_item['data']->subscription_length || ( 0 != $recurring_cart->end_date && date( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ) >= $recurring_cart->end_date ) ) { + if ( '1' == $cart_item['data']->subscription_length || ( 0 != $recurring_cart->end_date && gmdate( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ) >= $recurring_cart->end_date ) ) { $subscription->delete_date( 'next_payment' ); + $switch_order_data[ $subscription->id ]['dates']['delete'][] = 'next_payment'; } else if ( $is_different_payment_date ) { - $updated_dates['next_payment'] = date( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ); + $updated_dates['next_payment'] = gmdate( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ); } if ( $is_different_length ) { @@ -702,33 +735,45 @@ class WC_Subscriptions_Switcher { if ( ! empty( $updated_dates ) ) { $subscription->update_dates( $updated_dates ); + $switch_order_data[ $subscription->id ]['dates']['update'] = $updated_dates; } } // Remove the old item from the subscription but don't delete it completely by changing its line item type to "line_item_switched" wc_update_order_item( $cart_item['subscription_switch']['item_id'], array( 'order_item_type' => 'line_item_switched' ) ); - $old_item_name = wcs_get_order_item_name( $existing_item, array( 'attributes' => true ) ); - $new_item_name = wcs_get_cart_item_name( $cart_item, array( 'attributes' => true ) ); - - // translators: 1$: old item name, 2$: new item name when switching - $subscription->add_order_note( sprintf( _x( 'Customer switched from: %1$s to %2$s.', 'used in order notes', 'woocommerce-subscriptions' ), $old_item_name, $new_item_name ) ); - // Change the shipping self::update_shipping_methods( $subscription, $recurring_cart ); + $switch_order_data[ $subscription->id ]['shipping_methods'] = $subscription->get_shipping_methods(); // Finally, change the addresses but only if they've changed self::maybe_update_subscription_address( $order, $subscription ); - - $subscription->calculate_totals(); } } - // Everything seems to be in order - $wpdb->query( 'COMMIT' ); + // Everything seems to be in order. + // Rollback the changes and store the required meta on the order so it can be processed on successful payment. + $wpdb->query( 'ROLLBACK' ); + + foreach ( $switch_order_data as $subscription_id => $switch_data ) { + + // Cancel all the switch orders linked to the switched subscription(s) which haven't been completed yet - excluding this one. + $switch_orders = wcs_get_switch_orders_for_subscription( $subscription_id ); + + foreach ( $switch_orders as $switch_order_id => $switch_order ) { + if ( $order->id !== $switch_order_id && in_array( $switch_order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed', 'on-hold' ), $switch_order ) ) ) { + $switch_order->update_status( 'cancelled', sprintf( __( 'Switch order cancelled due to a new switch order being created #%s.', 'woocommerce-subscriptions' ), $order->get_order_number() ) ); + } + } + + // Despite rolling back the DB queries, the cache can still contain subscription changes (eg _billing_period post meta), so make sure we delete the cache for all subscriptions we've altered. + wp_cache_delete( $subscription_id, 'post_meta' ); + } + + update_post_meta( $order_id, '_subscription_switch_data', $switch_order_data ); } catch ( Exception $e ) { - // There was an error adding the subscription, roll back and delete pending order for switch + // There was an error updating the subscription, roll back and delete pending order for switch $wpdb->query( 'ROLLBACK' ); wp_delete_post( $order_id, true ); throw $e; @@ -919,6 +964,11 @@ class WC_Subscriptions_Switcher { $item_id = absint( $_GET['item'] ); $item = wcs_get_order_item( $item_id, $subscription ); + // Prevent switching to non-subscription product + if ( ! WC_Subscriptions_Product::is_subscription( $product_id ) ) { + throw new Exception( __( 'You can only switch to a subscription product.', 'woocommerce-subscriptions' ) ); + } + // Check if the chosen variation's attributes are different to the existing subscription's attributes (to support switching between a "catch all" variation) if ( empty( $item ) ) { @@ -1143,7 +1193,7 @@ class WC_Subscriptions_Switcher { // Set when the first payment and end date for the new subscription should occur WC()->cart->cart_contents[ $cart_item_key ]['subscription_switch']['first_payment_timestamp'] = $cart_item['subscription_switch']['next_payment_timestamp']; - WC()->cart->cart_contents[ $cart_item_key ]['subscription_switch']['end_timestamp'] = $end_timestamp = strtotime( WC_Subscriptions_Product::get_expiration_date( $product_id, $subscription->get_date( 'last_payment' ) ) ); + WC()->cart->cart_contents[ $cart_item_key ]['subscription_switch']['end_timestamp'] = $end_timestamp = wcs_date_to_time( WC_Subscriptions_Product::get_expiration_date( $product_id, $subscription->get_date( 'last_payment' ) ) ); // Add any extra sign up fees required to switch to the new subscription if ( 'yes' == $apportion_sign_up_fee ) { @@ -1228,11 +1278,12 @@ class WC_Subscriptions_Switcher { // Find out how many days at the new price per day the customer would receive for the total amount already paid // (e.g. if the customer paid $10 / month previously, and was switching to a $5 / week subscription, she has pre-paid 14 days at the new price) - $pre_paid_days = 0; - do { + $pre_paid_days = $new_total_paid = 0; + + while ( $new_total_paid < $old_recurring_total ) { $pre_paid_days++; $new_total_paid = $pre_paid_days * $new_price_per_day; - } while ( $new_total_paid < $old_recurring_total ); + } // If the total amount the customer has paid entitles her to more days at the new price than she has received, there is no gap payment, just shorten the pre-paid term the appropriate number of days if ( $days_since_last_payment < $pre_paid_days ) { @@ -1321,8 +1372,8 @@ class WC_Subscriptions_Switcher { public static function recurring_cart_next_payment_date( $first_renewal_date, $cart ) { foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { - if ( isset( $cart_item['subscription_switch']['first_payment_timestamp'] ) ) { - $first_renewal_date = ( '1' != $cart_item['data']->subscription_length ) ? date( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ) : 0; + if ( isset( $cart_item['subscription_switch']['first_payment_timestamp'] ) && 0 != $cart_item['subscription_switch']['first_payment_timestamp'] ) { + $first_renewal_date = ( '1' != $cart_item['data']->subscription_length ) ? gmdate( 'Y-m-d H:i:s', $cart_item['subscription_switch']['first_payment_timestamp'] ) : 0; } } @@ -1345,7 +1396,7 @@ class WC_Subscriptions_Switcher { // if the subscription is length 1 and prorated, we want to use the prorated the next payment date as the end date if ( 1 == $cart_item['data']->subscription_length && 0 !== $next_payment_time && isset( $cart_item['subscription_switch']['recurring_payment_prorated'] ) ) { - $end_date = date( 'Y-m-d H:i:s', $next_payment_time ); + $end_date = gmdate( 'Y-m-d H:i:s', $next_payment_time ); // if the subscription is more than 1 (and not 0) and we have a next payment date (prorated or not) we want to calculate the new end date from that } elseif ( 0 !== $next_payment_time && $cart_item['data']->subscription_length > 1 ) { @@ -1353,14 +1404,14 @@ class WC_Subscriptions_Switcher { $trial_length = $cart_item['data']->subscription_trial_length; $cart_item['data']->subscription_trial_length = 0; - $end_date = WC_Subscriptions_Product::get_expiration_date( $cart_item['data'], date( 'Y-m-d H:i:s', $next_payment_time ) ); + $end_date = WC_Subscriptions_Product::get_expiration_date( $cart_item['data'], gmdate( 'Y-m-d H:i:s', $next_payment_time ) ); // add back the trial length if it has been spoofed $cart_item['data']->subscription_trial_length = $trial_length; // elseif fallback to using the end date set on the cart item } elseif ( ! empty( $end_timestamp ) ) { - $end_date = date( 'Y-m-d H:i:s', $end_timestamp ); + $end_date = gmdate( 'Y-m-d H:i:s', $end_timestamp ); } break; @@ -1420,41 +1471,11 @@ class WC_Subscriptions_Switcher { * * @since 1.4.4 * @return bool + * @deprecated 2.1 */ public static function is_purchasable( $is_purchasable, $product ) { - - $product_key = ! empty( $product->variation_id ) ? $product->variation_id : $product->id; - - if ( ! isset( self::$is_purchasable_cache[ $product_key ] ) ) { - - if ( false === $is_purchasable && wcs_is_product_switchable_type( $product ) && WC_Subscriptions_Product::is_subscription( $product->id ) && 'no' != $product->limit_subscriptions && is_user_logged_in() && wcs_user_has_subscription( 0, $product->id, $product->limit_subscriptions ) ) { - - // Adding to cart from the product page - if ( isset( $_GET['switch-subscription'] ) ) { - - $is_purchasable = true; - - // Validating when restring cart from session - } elseif ( self::cart_contains_switches() ) { - - $is_purchasable = true; - - // Restoring cart from session, so need to check the cart in the session (self::cart_contains_subscription_switch() only checks the cart) - } elseif ( isset( WC()->session->cart ) ) { - - foreach ( WC()->session->cart as $cart_item_key => $cart_item ) { - if ( $product->id == $cart_item['product_id'] && isset( $cart_item['subscription_switch'] ) ) { - $is_purchasable = true; - break; - } - } - } - } - - self::$is_purchasable_cache[ $product_key ] = $is_purchasable; - } - - return self::$is_purchasable_cache[ $product_key ]; + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::is_purchasable_switch' ); + return WCS_Limiter::is_purchasable_switch( $is_purchasable, $product ); } /** @@ -1513,6 +1534,49 @@ class WC_Subscriptions_Switcher { return $add_to_cart_url; } + /** + * Completes subscription switches on completed order status changes. + * + * Commits all the changes calculated and saved by @see WC_Subscriptions_Switcher::process_checkout(), updating subscription + * line items, schedule, dates and totals to reflect the changes made in this switch order. + * + * @param int $order_id The post_id of a shop_order post/WC_Order object + * @param array $order_old_status The old order status + * @param array $order_new_status The new order status + * @since 2.1 + */ + public static function process_subscription_switches( $order_id, $order_old_status, $order_new_status ) { + global $wpdb; + + $switch_processed = get_post_meta( $order_id, '_completed_subscription_switch', true ); + $order = wc_get_order( $order_id ); + + if ( ! wcs_order_contains_switch( $order_id ) || 'true' == $switch_processed ) { + return; + } + + $order_completed = in_array( $order_new_status, array( apply_filters( 'woocommerce_payment_complete_order_status', 'processing', $order_id ), 'processing', 'completed' ) ); + + if ( $order_completed ) { + try { + // Start transaction if available + $wpdb->query( 'START TRANSACTION' ); + + self::complete_subscription_switches( $order ); + + update_post_meta( $order_id, '_completed_subscription_switch', 'true' ); + + $wpdb->query( 'COMMIT' ); + + } catch ( Exception $e ) { + $wpdb->query( 'ROLLBACK' ); + throw $e; + } + + do_action( 'woocommerce_subscriptions_switch_completed', $order ); + } + } + /** * Checks if a product can be switched based on it's type and the types which can be switched * @@ -1552,7 +1616,7 @@ class WC_Subscriptions_Switcher { */ public static function hidden_order_itemmeta( $hidden_meta_keys ) { - if ( ! defined( 'WCS_DEBUG' ) || true !== WCS_DEBUG ) { + if ( apply_filters( 'woocommerce_subscriptions_hide_switch_itemmeta', ! defined( 'WCS_DEBUG' ) || true !== WCS_DEBUG ) ) { $hidden_meta_keys = array_merge( $hidden_meta_keys, array( '_switched_subscription_item_id', '_switched_subscription_new_item_id', @@ -1656,7 +1720,6 @@ class WC_Subscriptions_Switcher { foreach ( $subscriptions as $subscription ) { foreach ( $subscription->get_items() as $new_order_item ) { if ( isset( $new_order_item['switched_subscription_item_id'] ) ) { - $product_id = wcs_get_canonical_product_id( $new_order_item ); // we need to check if the switch order contains the line item that has just been switched so that we don't call the hook on items that were previously switched in another order foreach ( $order->get_items() as $order_item ) { @@ -1687,6 +1750,142 @@ class WC_Subscriptions_Switcher { $product_id = wcs_get_canonical_product_id( $old_item ); WCS_Download_Handler::revoke_downloadable_file_permission( $product_id, $subscription->id, $subscription->customer_user ); + + } + + /** + * Completes subscription switches for switch order. + * + * Performs all the changes calculated and saved by @see WC_Subscriptions_Switcher::process_checkout(), updating subscription + * line items, schedule, dates and totals to reflect the changes made in this switch order. + * + * @param WC_Order $order + * @since 2.1 + */ + public static function complete_subscription_switches( $order ) { + + // Get the switch meta + $switch_order_data = get_post_meta( $order->id, '_subscription_switch_data', true ); + + // if we don't have an switch data, there is nothing to do here. Switch orders created prior to v2.1 won't have any data to process. + if ( empty( $switch_order_data ) || ! is_array( $switch_order_data ) ) { + return; + } + + foreach ( $switch_order_data as $subcription_id => $switch_data ) { + + $subscription = wcs_get_subscription( $subcription_id ); + + if ( ! $subscription instanceof WC_Subscription ) { + continue; + } + + // Add the new line items + if ( ! empty( $switch_data['switches'] ) ) { + + foreach ( $switch_data['switches'] as $order_item_id => $switch_item_data ) { + + $order_item = wcs_get_order_item( $order_item_id, $order ); + + // if we are simply adding this product to an existing subscription + if ( isset( $switch_item_data['add_order_item_data'] ) ) { + $product = WC_Subscriptions::get_product( wcs_get_canonical_product_id( $order_item ) ); + $line_tax_data = wc_get_order_item_meta( $order_item_id, '_line_tax_data', true ); + $variation_attributes = ( method_exists( $product, 'get_variation_attributes' ) ) ? $product->get_variation_attributes() : array(); + + $item_id = $subscription->add_product( $product, $order_item['qty'], array( + 'variation' => $variation_attributes, + 'totals' => $switch_item_data['add_order_item_data']['totals'], + ) ); + + foreach ( $switch_item_data['add_order_item_data']['meta'] as $key => $value ) { + if ( ! array_key_exists( 'attribute_' . $key, $variation_attributes ) ) { + wc_add_order_item_meta( $item_id, $key, reset( $value ), true ); + } + } + + do_action( 'woocommerce_subscription_item_switched', $order, $subscription, $order_item_id, $switch_item_data['subscription_item_id'] ); + } + + // remove the existing subscription item + $old_order_item = wcs_get_order_item( $switch_item_data['subscription_item_id'], $subscription ); + + if ( empty( $old_order_item ) ) { + throw new Exception( __( 'The original subscription item being switched cannot be found.', 'woocommerce-subscriptions' ) ); + } else { + // We dont want to include switch item meta in order item name + add_filter( 'woocommerce_subscriptions_hide_switch_itemmeta', '__return_true' ); + $new_order_item_name = wcs_get_order_item_name( $order_item, array( 'attributes' => true ) ); + $old_subscription_item_name = wcs_get_order_item_name( $old_order_item, array( 'attributes' => true ) ); + remove_filter( 'woocommerce_subscriptions_hide_switch_itemmeta', '__return_true' ); + + wc_update_order_item( $switch_item_data['subscription_item_id'], array( 'order_item_type' => 'line_item_switched' ) ); + + // translators: 1$: old item, 2$: new item when switching + $subscription->add_order_note( sprintf( _x( 'Customer switched from: %1$s to %2$s.', 'used in order notes', 'woocommerce-subscriptions' ), $old_subscription_item_name, $new_order_item_name ) ); + } + } + } + + if ( ! empty( $switch_data['billing_schedule'] ) ) { + + // Update the billing schedule + foreach ( $switch_data['billing_schedule'] as $meta_key => $value ) { + update_post_meta( $subcription_id, $meta_key, $value ); + } + } + + // Update subscription dates + if ( ! empty( $switch_data['dates'] ) ) { + + if ( ! empty( $switch_data['dates']['delete'] ) ) { + foreach ( $switch_data['dates']['delete'] as $date ) { + $subscription->delete_date( $date ); + } + } + + if ( ! empty( $switch_data['dates']['update'] ) ) { + $subscription->update_dates( $switch_order_data[ $subscription->id ]['dates']['update'] ); + } + } + + if ( ! empty( $switch_data['shipping_methods'] ) ) { + + // Archive the old subscription shipping methods + foreach ( $subscription->get_shipping_methods() as $shipping_line_item_id => $item ) { + wc_update_order_item( $shipping_line_item_id, array( 'order_item_type' => 'shipping_switched' ) ); + } + + // Add the new shipping line item + foreach ( $switch_data['shipping_methods'] as $shipping_line_item ) { + $item_id = wc_add_order_item( $subscription->id, array( + 'order_item_name' => $shipping_line_item['name'], + 'order_item_type' => 'shipping', + ) ); + + if ( ! $item_id || empty( $shipping_line_item['method_id'] ) || empty( $shipping_line_item['cost'] ) || empty( $shipping_line_item['taxes'] ) ) { + throw new Exception( __( 'Failed to update the subscription shipping method.', 'woocommerce-subscriptions' ) ); + } + + // Add shipping order item meta + wc_add_order_item_meta( $item_id, 'method_id', $shipping_line_item['method_id'] ); + wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $shipping_line_item['cost'] ) ); + + $taxes = array_map( 'wc_format_decimal', maybe_unserialize( $shipping_line_item['taxes'] ) ); + wc_add_order_item_meta( $item_id, 'taxes', $taxes ); + + // Add custom shipping order item meta added by third-party plugins + foreach ( $shipping_line_item['item_meta'] as $key => $value ) { + wc_add_order_item_meta( $item_id, $key, $value ); + } + } + } + + // Update the subscription address + self::maybe_update_subscription_address( $order, $subscription ); + + $subscription->calculate_totals(); + } } /** @@ -1771,40 +1970,75 @@ class WC_Subscriptions_Switcher { * payment was completed with a payment method which supports automatic payments, update the payment on the subscription * and the manual renewals flag so that future renewals are processed automatically. * - * @param array $payment_processing_result - * @param int $order_id - * @since 2.0.16 + * @param WC_Order $order + * @since 2.1 */ - public static function maybe_set_payment_method( $payment_processing_result, $order_id ) { + public static function maybe_set_payment_method_after_switch( $order ) { - // Only update the payment method the order contains a switch, and payment was processed (i.e. a paid date has been set) not just setup for processing, which is the case with PayPal Standard (which is handled by WCS_PayPal_Standard_Switcher) - if ( wcs_order_contains_switch( $order_id ) && false != get_post_meta( $order_id, '_paid_date', true ) ) { + foreach ( wcs_get_subscriptions_for_switch_order( $order->id ) as $subscription ) { - $order = wc_get_order( $order_id ); + if ( false === $subscription->is_manual() ) { + continue; + } - foreach ( wcs_get_subscriptions_for_switch_order( $order_id ) as $subscription ) { + if ( $subscription->payment_method !== $order->payment_method ) { - if ( false === $subscription->is_manual() ) { - continue; - } + // Set the new payment method on the subscription + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + $payment_method = isset( $available_gateways[ $order->payment_method ] ) ? $available_gateways[ $order->payment_method ] : false; - if ( $subscription->payment_method !== $order->payment_method ) { - - // Set the new payment method on the subscription - $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); - $payment_method = isset( $available_gateways[ $order->payment_method ] ) ? $available_gateways[ $order->payment_method ] : false; - - if ( $payment_method && $payment_method->supports( 'subscriptions' ) ) { - $subscription->set_payment_method( $payment_method ); - $subscription->update_manual( false ); - } + if ( $payment_method && $payment_method->supports( 'subscriptions' ) ) { + $subscription->set_payment_method( $payment_method ); + $subscription->update_manual( false ); } } } + } + + /** Deprecated Methods **/ + + /** + * Once payment is processed on a switch from a $0 / period subscription to a non-zero $ / period subscription, if + * payment was completed with a payment method which supports automatic payments, update the payment on the subscription + * and the manual renewals flag so that future renewals are processed automatically. + * + * @param array $payment_processing_result + * @param int $order_id + * @since 2.0.16 + * @deprecated 2.1 + */ + public static function maybe_set_payment_method( $payment_processing_result, $order_id ) { + + _deprecated_function( __METHOD__, '2.1', __CLASS__ . '::maybe_set_payment_method_after_switch( $order )' ); + + if ( wcs_order_contains_switch( $order_id ) && false != get_post_meta( $order_id, '_paid_date', true ) ) { + + $order = wc_get_order( $order_id ); + self::maybe_set_payment_method_after_switch( $order ); + } return $payment_processing_result; } + /** + * Override the order item quantity used to reduce stock levels when the order item is to record a switch and where no + * prorated amount is being charged. + * + * @param int $quantity the original order item quantity used to reduce stock + * @param WC_Order $order + * @param array $order_item + * + * @return int + */ + public static function maybe_do_not_reduce_stock( $quantity, $order, $order_item ) { + + if ( isset( $order_item['switched_subscription_price_prorated'] ) && 0 == $order_item['line_total'] ) { + $quantity = 0; + } + + return $quantity; + } + /** * Make sure switch cart item price doesn't include any recurring amount by setting a free trial. * @@ -1999,7 +2233,7 @@ class WC_Subscriptions_Switcher { $first_payment_timestamp = get_post_meta( $subscription->order->id, '_switched_subscription_first_payment_timestamp', true ); if ( 0 != $first_payment_timestamp ) { - $next_payment_date = ( 'mysql' == $type ) ? date( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; + $next_payment_date = ( 'mysql' == $type ) ? gmdate( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; } } diff --git a/includes/class-wc-subscriptions-synchroniser.php b/includes/class-wc-subscriptions-synchroniser.php index 52530fa..c9c3c53 100644 --- a/includes/class-wc-subscriptions-synchroniser.php +++ b/includes/class-wc-subscriptions-synchroniser.php @@ -44,10 +44,10 @@ class WC_Subscriptions_Synchroniser { self::$setting_id = WC_Subscriptions_Admin::$option_prefix . '_sync_payments'; self::$setting_id_proration = WC_Subscriptions_Admin::$option_prefix . '_prorate_synced_payments'; - self::$sync_field_label = __( 'Synchronise Renewals', 'woocommerce-subscriptions' ); + self::$sync_field_label = __( 'Synchronise renewals', 'woocommerce-subscriptions' ); self::$sync_description = __( 'Align the payment date for all customers who purchase this subscription to a specific day of the week or month.', 'woocommerce-subscriptions' ); // translators: placeholder is a year (e.g. "2016") - self::$sync_description_year = sprintf( _x( 'Align the payment date for this subscription to a specific day of the year. If the date has already taken place this year, the first payment will be processed in %s. Set the day to 0 to disable payment syncing for this product.', 'used in subscription product edit screen', 'woocommerce-subscriptions' ), date( 'Y', strtotime( '+1 year' ) ) ); + self::$sync_description_year = sprintf( _x( 'Align the payment date for this subscription to a specific day of the year. If the date has already taken place this year, the first payment will be processed in %s. Set the day to 0 to disable payment syncing for this product.', 'used in subscription product edit screen', 'woocommerce-subscriptions' ), gmdate( 'Y', wcs_date_to_time( '+1 year' ) ) ); // Add the settings to control whether syncing is enabled and how it will behave add_filter( 'woocommerce_subscription_settings', __CLASS__ . '::add_settings' ); @@ -149,7 +149,7 @@ class WC_Subscriptions_Synchroniser { 'name' => __( 'Synchronisation', 'woocommerce-subscriptions' ), 'type' => 'title', // translators: placeholders are opening and closing link tags - 'desc' => sprintf( _x( 'Align subscription renewal to a specific day of the week, month or year. For example, the first day of the month. %sLearn more%s.', 'used in the general subscription options page', 'woocommerce-subscriptions' ), '', '' ), + 'desc' => sprintf( _x( 'Align subscription renewal to a specific day of the week, month or year. For example, the first day of the month. %sLearn more%s.', 'used in the general subscription options page', 'woocommerce-subscriptions' ), '', '' ), 'id' => self::$setting_id . '_title', ), @@ -208,7 +208,7 @@ class WC_Subscriptions_Synchroniser { $payment_month = $payment_day['month']; $payment_day = $payment_day['day']; } else { - $payment_month = date( 'm' ); + $payment_month = gmdate( 'm' ); } echo '

'; @@ -216,8 +216,8 @@ class WC_Subscriptions_Synchroniser { woocommerce_wp_select( array( 'id' => self::$post_meta_key, - 'class' => 'wc_input_subscription_payment_sync', - 'label' => self::$sync_field_label . ':', + 'class' => 'wc_input_subscription_payment_sync select short', + 'label' => self::$sync_field_label, 'options' => self::get_billing_period_ranges( $subscription_period ), 'description' => self::$sync_description, 'desc_tip' => true, @@ -229,26 +229,22 @@ class WC_Subscriptions_Synchroniser { echo '
'; - woocommerce_wp_text_input( array( - 'id' => self::$post_meta_key_day, - 'class' => 'wc_input_subscription_payment_sync', - 'label' => self::$sync_field_label . ':', - 'placeholder' => _x( 'Day', 'input field placeholder for day field for annual subscriptions', 'woocommerce-subscriptions' ), - 'value' => $payment_day, - 'type' => 'number', - ) - ); + ?>

+ + + - woocommerce_wp_select( array( - 'id' => self::$post_meta_key_month, - 'class' => 'wc_input_subscription_payment_sync', - 'label' => '', - 'options' => $wp_locale->month, - 'description' => self::$sync_description_year, - 'desc_tip' => true, - 'value' => $payment_month, // Explicity set value in to ensure backward compatibility - ) - ); + + + + + + +

'; echo '
'; @@ -280,7 +276,7 @@ class WC_Subscriptions_Synchroniser { $payment_month = $payment_day['month']; $payment_day = $payment_day['day']; } else { - $payment_month = date( 'm' ); + $payment_month = gmdate( 'm' ); } include( plugin_dir_path( WC_Subscriptions::$plugin_file ) . 'templates/admin/html-variation-synchronisation.php' ); @@ -494,14 +490,14 @@ class WC_Subscriptions_Synchroniser { $from_date = WC_Subscriptions_Product::get_trial_expiration_date( $product, $from_date ); } - $from_timestamp = strtotime( $from_date ) + ( get_option( 'gmt_offset' ) * 3600 ); // Site time + $from_timestamp = wcs_date_to_time( $from_date ) + ( get_option( 'gmt_offset' ) * 3600 ); // Site time $payment_day = self::get_products_payment_day( $product ); if ( 'week' == $period ) { // strtotime() will figure out if the day is in the future or today (see: https://gist.github.com/thenbrent/9698083) - $first_payment_timestamp = strtotime( self::$weekdays[ $payment_day ], $from_timestamp ); + $first_payment_timestamp = wcs_strtotime_dark_knight( self::$weekdays[ $payment_day ], $from_timestamp ); } elseif ( 'month' == $period ) { @@ -513,7 +509,7 @@ class WC_Subscriptions_Synchroniser { } elseif ( gmdate( 'j', $from_timestamp ) > $payment_day ) { // today is later than specified day in the from date, we need the next month - $month = date( 'F', wcs_add_months( $from_timestamp, 1 ) ); + $month = gmdate( 'F', wcs_add_months( $from_timestamp, 1 ) ); } else { // specified day is either today or still to come in the month of the from date @@ -521,7 +517,7 @@ class WC_Subscriptions_Synchroniser { } - $first_payment_timestamp = strtotime( "{$payment_day} {$month}", $from_timestamp ); + $first_payment_timestamp = wcs_strtotime_dark_knight( "{$payment_day} {$month}", $from_timestamp ); } elseif ( 'year' == $period ) { @@ -565,7 +561,7 @@ class WC_Subscriptions_Synchroniser { break; } - $first_payment_timestamp = strtotime( "{$payment_day['day']} {$month}", $from_timestamp ); + $first_payment_timestamp = wcs_strtotime_dark_knight( "{$payment_day['day']} {$month}", $from_timestamp ); } // Make sure the next payment is in the future and after the $from_date, as strtotime() will return the date this year for any day in the past when adding months or years (see: https://gist.github.com/thenbrent/9698083) @@ -576,7 +572,7 @@ class WC_Subscriptions_Synchroniser { $i = 1; // Then make sure the date and time of the payment is in the future while ( ( $first_payment_timestamp < gmdate( 'U' ) || $first_payment_timestamp < $from_timestamp ) && $i < 30 ) { - $first_payment_timestamp = strtotime( "+ 1 {$period}", $first_payment_timestamp ); + $first_payment_timestamp = wcs_add_time( 1, $period, $first_payment_timestamp ); $i = $i + 1; } } @@ -588,7 +584,7 @@ class WC_Subscriptions_Synchroniser { // And convert it to the UTC equivalent of 3am on that day $first_payment_timestamp -= ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); - $first_payment = ( 'mysql' == $type && 0 != $first_payment_timestamp ) ? date( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; + $first_payment = ( 'mysql' == $type && 0 != $first_payment_timestamp ) ? gmdate( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; return apply_filters( 'woocommerce_subscriptions_synced_first_payment_date', $first_payment, $product, $type, $from_date, $from_date_param ); } @@ -834,7 +830,7 @@ class WC_Subscriptions_Synchroniser { // Convert timestamp to site's time $timestamp += get_option( 'gmt_offset' ) * HOUR_IN_SECONDS; - return ( gmdate( 'Y-m-d', current_time( 'timestamp' ) ) == date( 'Y-m-d', $timestamp ) ) ? true : false; + return ( gmdate( 'Y-m-d', current_time( 'timestamp' ) ) == gmdate( 'Y-m-d', $timestamp ) ) ? true : false; } /** @@ -876,10 +872,10 @@ class WC_Subscriptions_Synchroniser { $days_in_cycle = 7 * $product->subscription_period_interval; break; case 'month' : - $days_in_cycle = date( 't' ) * $product->subscription_period_interval; + $days_in_cycle = gmdate( 't' ) * $product->subscription_period_interval; break; case 'year' : - $days_in_cycle = ( 365 + date( 'L' ) ) * $product->subscription_period_interval; + $days_in_cycle = ( 365 + gmdate( 'L' ) ) * $product->subscription_period_interval; break; } @@ -1194,7 +1190,7 @@ class WC_Subscriptions_Synchroniser { $first_payment_timestamp = self::calculate_first_payment_date( $product_id, 'timestamp', $order->order_date ); if ( 0 != $first_payment_timestamp ) { - $first_payment_date = ( 'mysql' == $type ) ? date( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; + $first_payment_date = ( 'mysql' == $type ) ? gmdate( 'Y-m-d H:i:s', $first_payment_timestamp ) : $first_payment_timestamp; } } } @@ -1217,7 +1213,7 @@ class WC_Subscriptions_Synchroniser { $first_payment_date = self::get_first_payment_date( $payment_date, $order, $product_id, 'timestamp' ); if ( ! self::is_today( $first_payment_date ) ) { - $payment_date = ( 'timestamp' == $type ) ? $first_payment_date : date( 'Y-m-d H:i:s', $first_payment_date ); + $payment_date = ( 'timestamp' == $type ) ? $first_payment_date : gmdate( 'Y-m-d H:i:s', $first_payment_date ); } return $payment_date; @@ -1326,7 +1322,7 @@ class WC_Subscriptions_Synchroniser { public static function recalculate_trial_end_date( $trial_end_date, $recurring_cart, $product ) { _deprecated_function( __METHOD__, '2.0.14' ); if ( self::is_product_synced( $product ) ) { - $product_id = ( isset( $product->variation_id ) ) ? $product->variation_id : $product->id; + $product_id = wcs_get_canonical_product_id( $product ); $trial_end_date = WC_Subscriptions_Product::get_trial_expiration_date( $product_id ); } @@ -1343,7 +1339,7 @@ class WC_Subscriptions_Synchroniser { public static function recalculate_end_date( $end_date, $recurring_cart, $product ) { _deprecated_function( __METHOD__, '2.0.14' ); if ( self::is_product_synced( $product ) ) { - $product_id = ( isset( $product->variation_id ) ) ? $product->variation_id : $product->id; + $product_id = wcs_get_canonical_product_id( $product ); $end_date = WC_Subscriptions_Product::get_expiration_date( $product_id ); } diff --git a/includes/class-wcs-action-scheduler.php b/includes/class-wcs-action-scheduler.php index 4674bd5..d37636f 100644 --- a/includes/class-wcs-action-scheduler.php +++ b/includes/class-wcs-action-scheduler.php @@ -12,17 +12,17 @@ class WCS_Action_Scheduler extends WCS_Scheduler { /*@protected Array of $action_hook => $date_type values */ protected $action_hooks = array( - 'woocommerce_scheduled_subscription_trial_end' => 'trial_end', - 'woocommerce_scheduled_subscription_payment' => 'next_payment', - 'woocommerce_scheduled_subscription_expiration' => 'end', - + 'woocommerce_scheduled_subscription_trial_end' => 'trial_end', + 'woocommerce_scheduled_subscription_payment' => 'next_payment', + 'woocommerce_scheduled_subscription_payment_retry' => 'payment_retry', + 'woocommerce_scheduled_subscription_expiration' => 'end', ); /** * Maybe set a schedule action if the new date is in the future * * @param object $subscription An instance of a WC_Subscription object - * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'end', 'end_of_prepaid_term' or a custom date type + * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'payment_retry', 'last_payment', 'end', 'end_of_prepaid_term' or a custom date type * @param string $datetime A MySQL formated date/time string in the GMT/UTC timezone. */ public function update_date( $subscription, $date_type, $datetime ) { @@ -33,8 +33,8 @@ class WCS_Action_Scheduler extends WCS_Scheduler { if ( ! empty( $action_hook ) ) { - $action_args = array( 'subscription_id' => $subscription->id ); - $timestamp = strtotime( $datetime ); + $action_args = $this->get_action_args( $date_type, $subscription ); + $timestamp = wcs_date_to_time( $datetime ); $next_scheduled = wc_next_scheduled_action( $action_hook, $action_args ); if ( $next_scheduled !== $timestamp ) { @@ -45,8 +45,8 @@ class WCS_Action_Scheduler extends WCS_Scheduler { } // Only reschedule if it's in the future - if ( $timestamp > current_time( 'timestamp', true ) && 'active' == $subscription->get_status() ) { - wc_schedule_single_action( $datetime, $action_hook, $action_args ); + if ( $timestamp > current_time( 'timestamp', true ) && ( 'payment_retry' == $date_type || 'active' == $subscription->get_status() ) ) { + wc_schedule_single_action( $timestamp, $action_hook, $action_args ); } } } @@ -72,13 +72,12 @@ class WCS_Action_Scheduler extends WCS_Scheduler { */ public function update_status( $subscription, $new_status, $old_status ) { - $action_args = array( 'subscription_id' => $subscription->id ); - switch ( $new_status ) { case 'active' : foreach ( $this->action_hooks as $action_hook => $date_type ) { + $action_args = $this->get_action_args( $date_type, $subscription ); $next_scheduled = wc_next_scheduled_action( $action_hook, $action_args ); $event_time = $subscription->get_time( $date_type ); @@ -98,9 +97,10 @@ class WCS_Action_Scheduler extends WCS_Scheduler { // Now that we have the current times, clear the scheduled hooks foreach ( $this->action_hooks as $action_hook => $date_type ) { - wc_unschedule_action( $action_hook, $action_args ); + wc_unschedule_action( $action_hook, $this->get_action_args( $date_type, $subscription ) ); } + $action_args = $this->get_action_args( 'end', $subscription ); $next_scheduled = wc_next_scheduled_action( 'woocommerce_scheduled_subscription_end_of_prepaid_term', $action_args ); if ( false !== $next_scheduled && $next_scheduled != $end_time ) { @@ -118,9 +118,9 @@ class WCS_Action_Scheduler extends WCS_Scheduler { case 'expired' : case 'trash' : foreach ( $this->action_hooks as $action_hook => $date_type ) { - wc_unschedule_action( $action_hook, $action_args ); + wc_unschedule_action( $action_hook, $this->get_action_args( $date_type, $subscription ) ); } - wc_unschedule_action( 'woocommerce_scheduled_subscription_end_of_prepaid_term', $action_args ); + wc_unschedule_action( 'woocommerce_scheduled_subscription_end_of_prepaid_term', $this->get_action_args( 'end', $subscription ) ); break; } } @@ -128,8 +128,8 @@ class WCS_Action_Scheduler extends WCS_Scheduler { /** * Get the hook to use in the action scheduler for the date type * - * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'expiration', 'end_of_prepaid_term' or a custom date type * @param object $subscription An instance of WC_Subscription to get the hook for + * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'expiration', 'end_of_prepaid_term' or a custom date type */ protected function get_scheduled_action_hook( $subscription, $date_type ) { @@ -139,6 +139,9 @@ class WCS_Action_Scheduler extends WCS_Scheduler { case 'next_payment' : $hook = 'woocommerce_scheduled_subscription_payment'; break; + case 'payment_retry' : + $hook = 'woocommerce_scheduled_subscription_payment_retry'; + break; case 'trial_end' : $hook = 'woocommerce_scheduled_subscription_trial_end'; break; @@ -154,4 +157,24 @@ class WCS_Action_Scheduler extends WCS_Scheduler { return apply_filters( 'woocommerce_subscriptions_scheduled_action_hook', $hook, $date_type ); } + + /** + * Get the args to set on the scheduled action. + * + * @param string $date_type Can be 'start', 'trial_end', 'next_payment', 'last_payment', 'expiration', 'end_of_prepaid_term' or a custom date type + * @param object $subscription An instance of WC_Subscription to get the hook for + */ + protected function get_action_args( $date_type, $subscription ) { + + if ( 'payment_retry' == $date_type ) { + + $last_order_id = $subscription->get_last_order( 'ids', 'renewal' ); + $action_args = array( 'order_id' => $last_order_id ); + + } else { + $action_args = array( 'subscription_id' => $subscription->id ); + } + + return apply_filters( 'woocommerce_subscriptions_scheduled_action_args', $action_args, $date_type, $subscription ); + } } diff --git a/includes/class-wcs-api.php b/includes/class-wcs-api.php index 5f9ee48..1eebb91 100644 --- a/includes/class-wcs-api.php +++ b/includes/class-wcs-api.php @@ -17,6 +17,7 @@ class WCS_API { public static function init() { add_filter( 'woocommerce_api_classes', __CLASS__ . '::includes' ); + add_action( 'rest_api_init', __CLASS__ . '::register_routes', 15 ); } /** @@ -28,16 +29,40 @@ class WCS_API { * @return array */ public static function includes( $wc_api_classes ) { - // include the subscription api classes - require_once( 'api/class-wc-api-subscriptions.php' ); - require_once( 'api/class-wc-api-subscriptions-customers.php' ); - array_push( $wc_api_classes, 'WC_API_Subscriptions' ); - array_push( $wc_api_classes, 'WC_API_Subscriptions_Customers' ); + if ( ! defined( 'WC_API_REQUEST_VERSION' ) || 3 == WC_API_REQUEST_VERSION ) { + + require_once( 'api/legacy/class-wc-api-subscriptions.php' ); + require_once( 'api/legacy/class-wc-api-subscriptions-customers.php' ); + + array_push( $wc_api_classes, 'WC_API_Subscriptions' ); + array_push( $wc_api_classes, 'WC_API_Subscriptions_Customers' ); + } return $wc_api_classes; } + /** + * Load the new REST API subscription endpoints + * + * @since 2.1 + */ + public static function register_routes() { + global $wp_version; + + if ( version_compare( $wp_version, 4.4, '<' ) || WC_Subscriptions::is_woocommerce_pre( '2.6' ) ) { + return; + } + + require_once( 'api/class-wc-rest-subscriptions-controller.php' ); + require_once( 'api/class-wc-rest-subscription-notes-controller.php' ); + + foreach ( array( 'WC_REST_Subscriptions_Controller', 'WC_REST_Subscription_Notes_Controller' ) as $api_class ) { + $controller = new $api_class(); + $controller->register_routes(); + } + } + } WCS_API::init(); diff --git a/includes/class-wcs-cart-initial-payment.php b/includes/class-wcs-cart-initial-payment.php index 4db7fa1..3f6b08b 100644 --- a/includes/class-wcs-cart-initial-payment.php +++ b/includes/class-wcs-cart-initial-payment.php @@ -39,18 +39,26 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal { $order_id = ( isset( $wp->query_vars['order-pay'] ) ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] ); $order = wc_get_order( $wp->query_vars['order-pay'] ); - if ( $order->order_key == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && ! wcs_order_contains_subscription( $order, array( 'renewal', 'resubscribe' ) ) ) { + if ( $order->order_key == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_subscription( $order, 'parent' ) && ! wcs_order_contains_subscription( $order, 'resubscribe' ) ) { - $subscriptions = wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ); + if ( ! is_user_logged_in() ) { - if ( get_current_user_id() !== $order->get_user_id() ) { + $redirect = add_query_arg( array( + 'wcs_redirect' => 'pay_for_order', + 'wcs_redirect_id' => $order_id, + ), get_permalink( wc_get_page_id( 'myaccount' ) ) ); + + wp_safe_redirect( $redirect ); + exit; + + } elseif ( ! current_user_can( 'pay_for_order', $order_id ) ) { wc_add_notice( __( 'That doesn\'t appear to be your order.', 'woocommerce-subscriptions' ), 'error' ); wp_safe_redirect( get_permalink( wc_get_page_id( 'myaccount' ) ) ); exit; - } elseif ( ! empty( $subscriptions ) ) { + } else { // Setup cart with all the original order's line items $this->setup_cart( $order, array( diff --git a/includes/class-wcs-cart-renewal.php b/includes/class-wcs-cart-renewal.php index e88f8a6..a7a6da0 100644 --- a/includes/class-wcs-cart-renewal.php +++ b/includes/class-wcs-cart-renewal.php @@ -37,6 +37,12 @@ class WCS_Cart_Renewal { // When a failed renewal order is paid for via checkout, make sure WC_Checkout::create_order() preserves its "failed" status until it is paid add_filter( 'woocommerce_default_order_status', array( &$this, 'maybe_preserve_order_status' ) ); + + // When a failed/pending renewal order is paid for via checkout, ensure a new order isn't created due to mismatched cart hashes + add_filter( 'woocommerce_create_order', array( &$this, 'set_renewal_order_cart_hash' ), 10, 1 ); + + // When a user is prevented from paying for a failed/pending renewal order because they aren't logged in, redirect them back after login + add_filter( 'woocommerce_login_redirect', array( &$this, 'maybe_redirect_after_login' ), 10 , 1 ); } /** @@ -53,10 +59,6 @@ class WCS_Cart_Renewal { // Make sure fees are added to the cart add_action( 'woocommerce_cart_calculate_fees', array( &$this, 'maybe_add_fees' ), 10, 1 ); - // Allow renewal of limited subscriptions - add_filter( 'woocommerce_subscription_is_purchasable', array( &$this, 'is_purchasable' ), 12, 2 ); - add_filter( 'woocommerce_subscription_variation_is_purchasable', array( &$this, 'is_purchasable' ), 12, 2 ); - // Check if a user is requesting to create a renewal order for a subscription, needs to happen after $wp->query_vars are set add_action( 'template_redirect', array( &$this, 'maybe_setup_cart' ), 100 ); @@ -75,6 +77,12 @@ class WCS_Cart_Renewal { // Use original order price when resubscribing to products with addons (to ensure the adds on prices are included) add_filter( 'woocommerce_product_addons_adjust_price', array( &$this, 'product_addons_adjust_price' ), 10, 2 ); + + // When loading checkout address details, use the renewal order address details for renewals + add_filter( 'woocommerce_checkout_get_value', array( &$this, 'checkout_get_value' ), 10, 2 ); + + // If the shipping address on a renewal order differs to the order's billing address, check the "Ship to different address" automatically to make sure the renewal order's fields are used by default + add_filter( 'woocommerce_ship_to_different_address_checked', array( &$this, 'maybe_check_ship_to_different_address' ), 100, 1 ); } /** @@ -97,6 +105,25 @@ class WCS_Cart_Renewal { if ( $order->order_key == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_renewal( $order ) ) { + // If a user isn't logged in, allow them to login first and then redirect back + if ( ! is_user_logged_in() ) { + + $redirect = add_query_arg( array( + 'wcs_redirect' => 'pay_for_order', + 'wcs_redirect_id' => $order_id, + ), get_permalink( wc_get_page_id( 'myaccount' ) ) ); + + wp_safe_redirect( $redirect ); + exit; + + } elseif ( ! current_user_can( 'pay_for_order', $order_id ) ) { + + wc_add_notice( __( 'That doesn\'t appear to be your order.', 'woocommerce-subscriptions' ), 'error' ); + + wp_safe_redirect( get_permalink( wc_get_page_id( 'myaccount' ) ) ); + exit; + } + $subscriptions = wcs_get_subscriptions_for_renewal_order( $order ); do_action( 'wcs_before_renewal_setup_cart_subscriptions', $subscriptions, $order ); @@ -106,7 +133,7 @@ class WCS_Cart_Renewal { do_action( 'wcs_before_renewal_setup_cart_subscription', $subscription, $order ); // Add the existing subscription items to the cart - $this->setup_cart( $subscription, array( + $this->setup_cart( $order, array( 'subscription_id' => $subscription->id, 'renewal_order_id' => $order_id, ) ); @@ -119,9 +146,7 @@ class WCS_Cart_Renewal { if ( WC()->cart->cart_contents_count != 0 ) { // Store renewal order's ID in session so it can be re-used after payment WC()->session->set( 'order_awaiting_payment', $order_id ); - - // Set cart hash for orders paid in WC >= 2.6 - $this->set_cart_hash( $order_id ); + wc_add_notice( __( 'Complete checkout to renew your subscription.', 'woocommerce-subscriptions' ), 'success' ); } wp_safe_redirect( WC()->cart->get_checkout_url() ); @@ -146,6 +171,7 @@ class WCS_Cart_Renewal { $quantity = (int) $line_item['qty']; $variation_id = (int) $line_item['variation_id']; $variations = array(); + $item_data = array(); foreach ( $line_item['item_meta'] as $meta_name => $meta_value ) { if ( taxonomy_is_product_attribute( $meta_name ) ) { @@ -177,11 +203,15 @@ class WCS_Cart_Renewal { } } - if ( wcs_is_subscription( $subscription ) ) { - $cart_item_data['subscription_line_item_id'] = $item_id; + $cart_item_data['line_item_id'] = $item_id; + + $item_data = apply_filters( 'woocommerce_order_again_cart_item_data', array( $this->cart_item_key => $cart_item_data ), $line_item, $subscription ); + + if ( ! apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $item_data ) ) { + continue; } - $cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations, apply_filters( 'woocommerce_order_again_cart_item_data', array( $this->cart_item_key => $cart_item_data ), $line_item, $subscription ) ); + $cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations, $item_data ); $success = $success && (bool) $cart_item_key; } @@ -340,12 +370,12 @@ class WCS_Cart_Renewal { $_product = $cart_item_session_data['data']; - // Need to get the original subscription price, not the current price - $subscription = wcs_get_subscription( $cart_item[ $this->cart_item_key ]['subscription_id'] ); + // Need to get the original subscription or order price, not the current price + $subscription = $this->get_order( $cart_item ); if ( $subscription ) { $subscription_items = $subscription->get_items(); - $item_to_renew = $subscription_items[ $cart_item_session_data[ $this->cart_item_key ]['subscription_line_item_id'] ]; + $item_to_renew = $subscription_items[ $cart_item_session_data[ $this->cart_item_key ]['line_item_id'] ]; $price = $item_to_renew['line_subtotal']; @@ -376,6 +406,68 @@ class WCS_Cart_Renewal { return $cart_item_session_data; } + /** + * Returns address details from the renewal order if the checkout is for a renewal. + * + * @param string $value Default checkout field value. + * @param string $key The checkout form field name/key + * @return string $value Checkout field value. + */ + public function checkout_get_value( $value, $key ) { + + // Only hook in after WC()->checkout() has been initialised + if ( did_action( 'woocommerce_checkout_init' ) > 0 ) { + + $address_fields = array_merge( WC()->checkout()->checkout_fields['billing'], WC()->checkout()->checkout_fields['shipping'] ); + + if ( array_key_exists( $key, $address_fields ) && false !== ( $item = $this->cart_contains() ) ) { + + // Get the most specific order object, which will be the renewal order for renewals, initial order for initial payments, or a subscription for switches/resubscribes + $order = $this->get_order( $item ); + + if ( isset( $order->$key ) ) { + $value = $order->$key; + } + } + } + + return $value; + } + + /** + * If the cart contains a renewal order that needs to ship to an address that is different + * to the order's billing address, tell the checkout to toggle the ship to a different address + * checkbox and make sure the shipping fields are displayed by default. + * + * @param bool $ship_to_different_address Whether the order will ship to a different address + * @return bool $ship_to_different_address + */ + public function maybe_check_ship_to_different_address( $ship_to_different_address ) { + + if ( ! $ship_to_different_address && false !== ( $item = $this->cart_contains() ) ) { + + $order = $this->get_order( $item ); + + $renewal_shipping_address = $order->get_address( 'shipping' ); + $renewal_billing_address = $order->get_address( 'billing' ); + + if ( isset( $renewal_billing_address['email'] ) ) { + unset( $renewal_billing_address['email'] ); + } + + if ( isset( $renewal_billing_address['phone'] ) ) { + unset( $renewal_billing_address['phone'] ); + } + + // If the order's addresses are different, we need to display the shipping fields otherwise the billing address will override it + if ( $renewal_shipping_address != $renewal_billing_address ) { + $ship_to_different_address = 1; + } + } + + return $ship_to_different_address; + } + /** * When completing checkout for a subscription renewal, update the address on the subscription to use * the shipping/billing address entered in case it has changed since the subscription was first created. @@ -421,28 +513,9 @@ class WCS_Cart_Renewal { * @return bool */ public function is_purchasable( $is_purchasable, $product ) { + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::is_purchasable_renewal' ); + return WCS_Limiter::is_purchasable_renewal( $is_purchasable, $product ); - // If the product is being set as not-purchasable by Subscriptions (due to limiting) - if ( false === $is_purchasable && false === WC_Subscriptions_Product::is_purchasable( $is_purchasable, $product ) ) { - - // Adding to cart from the product page or paying for a renewal - if ( isset( $_GET[ $this->cart_item_key ] ) || isset( $_GET['subscription_renewal'] ) || $this->cart_contains() ) { - - $is_purchasable = true; - - } else if ( WC()->session->cart ) { - - foreach ( WC()->session->cart as $cart_item_key => $cart_item ) { - - if ( $product->id == $cart_item['product_id'] && isset( $cart_item['subscription_renewal'] ) ) { - $is_purchasable = true; - break; - } - } - } - } - - return $is_purchasable; } /** @@ -565,7 +638,7 @@ class WCS_Cart_Renewal { public function items_removed_title( $product_title, $cart_item ) { if ( isset( $cart_item[ $this->cart_item_key ]['subscription_id'] ) ) { - $subscription = wcs_get_subscription( absint( $cart_item[ $this->cart_item_key ]['subscription_id'] ) ); + $subscription = $this->get_order( $cart_item ); $product_title = ( count( $subscription->get_items() ) > 1 ) ? esc_html_x( 'All linked subscription items were', 'Used in WooCommerce by removed item notification: "_All linked subscription items were_ removed. Undo?" Filter for item title.', 'woocommerce-subscriptions' ) : $product_title; } @@ -785,6 +858,42 @@ class WCS_Cart_Renewal { update_post_meta( $order_id, '_cart_hash', md5( json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total ) ); } + /** + * Right before WC processes a renewal cart through the checkout, set the cart hash. + * This ensures legitimate changes to taxes and shipping methods don't cause a new order to be created. + * + * @param Mixed | An order generated by third party plugins + * @return Mixed | The unchanged order param + * @since 2.1.0 + */ + public function set_renewal_order_cart_hash( $order ) { + + if ( $item = wcs_cart_contains_renewal() ) { + $this->set_cart_hash( $item[ $this->cart_item_key ]['renewal_order_id'] ); + } + + return $order; + } + + /** + * Redirect back to pay for an order after successfully logging in. + * + * @param string | redirect URL after successful login + * @return string + * @since 2.1.0 + */ + function maybe_redirect_after_login( $redirect ) { + if ( isset( $_GET['wcs_redirect'], $_GET['wcs_redirect_id'] ) && 'pay_for_order' == $_GET['wcs_redirect'] ) { + $order = wc_get_order( $_GET['wcs_redirect_id'] ); + + if ( $order ) { + $redirect = $order->get_checkout_payment_url(); + } + } + + return $redirect; + } + /* Deprecated */ /** diff --git a/includes/class-wcs-cart-resubscribe.php b/includes/class-wcs-cart-resubscribe.php index e25674c..b3c960b 100644 --- a/includes/class-wcs-cart-resubscribe.php +++ b/includes/class-wcs-cart-resubscribe.php @@ -29,6 +29,24 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal { // When a resubscribe order is created on checkout, record the resubscribe, attached after WC_Subscriptions_Checkout::process_checkout() add_action( 'woocommerce_checkout_subscription_created', array( &$this, 'maybe_record_resubscribe' ), 10, 3 ); + + add_filter( 'woocommerce_subscriptions_recurring_cart_key', array( &$this, 'get_recurring_cart_key' ), 10, 2 ); + + add_filter( 'wcs_recurring_cart_next_payment_date', array( &$this, 'recurring_cart_next_payment_date' ), 100, 2 ); + + // Mock a free trial on the cart item to make sure the resubscribe total doesn't include any recurring amount when honoring prepaid term + add_filter( 'woocommerce_before_calculate_totals', array( &$this, 'maybe_set_free_trial' ), 100, 1 ); + add_action( 'woocommerce_subscription_cart_before_grouping', array( &$this, 'maybe_unset_free_trial' ) ); + add_action( 'woocommerce_subscription_cart_after_grouping', array( &$this, 'maybe_set_free_trial' ) ); + add_action( 'wcs_recurring_cart_start_date', array( &$this, 'maybe_unset_free_trial' ), 0, 1 ); + add_action( 'wcs_recurring_cart_end_date', array( &$this, 'maybe_set_free_trial' ), 100, 1 ); + add_filter( 'woocommerce_subscriptions_calculated_total', array( &$this, 'maybe_unset_free_trial' ), 10000, 1 ); + add_action( 'woocommerce_cart_totals_before_shipping', array( &$this, 'maybe_set_free_trial' ) ); + add_action( 'woocommerce_cart_totals_after_shipping', array( &$this, 'maybe_unset_free_trial' ) ); + add_action( 'woocommerce_review_order_before_shipping', array( &$this, 'maybe_set_free_trial' ) ); + add_action( 'woocommerce_review_order_after_shipping', array( &$this, 'maybe_unset_free_trial' ) ); + + add_action( 'woocommerce_order_status_changed', array( &$this, 'maybe_cancel_existing_subscription' ), 10, 3 ); } /** @@ -85,14 +103,31 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal { if ( $order->order_key == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_resubscribe( $order ) ) { + if ( ! is_user_logged_in() ) { + + $redirect = add_query_arg( array( + 'wcs_redirect' => 'pay_for_order', + 'wcs_redirect_id' => $order_id, + ), get_permalink( wc_get_page_id( 'myaccount' ) ) ); + + wp_safe_redirect( $redirect ); + exit; + } + wc_add_notice( __( 'Complete checkout to resubscribe.', 'woocommerce-subscriptions' ), 'success' ); $subscriptions = wcs_get_subscriptions_for_resubscribe_order( $order ); foreach ( $subscriptions as $subscription ) { - $this->setup_cart( $subscription, array( - 'subscription_id' => $subscription->id, - ) ); + if ( current_user_can( 'subscribe_again', $subscription->id ) ) { + $this->setup_cart( $subscription, array( + 'subscription_id' => $subscription->id, + ) ); + } else { + wc_add_notice( __( 'That doesn\'t appear to be one of your subscriptions.', 'woocommerce-subscriptions' ), 'error' ); + wp_safe_redirect( get_permalink( wc_get_page_id( 'myaccount' ) ) ); + exit; + } } $redirect_to = WC()->cart->get_checkout_url(); @@ -153,40 +188,9 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal { * @return bool */ public function is_purchasable( $is_purchasable, $product ) { + _deprecated_function( __METHOD__, '2.1', 'WCS_Limiter::is_purchasable_renewal' ); + return WCS_Limiter::is_purchasable_renewal( $is_purchasable, $product ); - // If the product is being set as not-purchasable by Subscriptions (due to limiting) - if ( false === $is_purchasable && false === WC_Subscriptions_Product::is_purchasable( $is_purchasable, $product ) ) { - - // Validating when restoring cart from session - if ( false !== $this->cart_contains() ) { - - $resubscribe_cart_item = $this->cart_contains(); - $subscription = wcs_get_subscription( $resubscribe_cart_item['subscription_resubscribe']['subscription_id'] ); - - if ( $subscription->has_product( $product->id ) ) { - $is_purchasable = true; - } - - // Restoring cart from session, so need to check the cart in the session (wcs_cart_contains_renewal() only checks the cart) - } elseif ( isset( WC()->session->cart ) ) { - - foreach ( WC()->session->cart as $cart_item_key => $cart_item ) { - if ( $product->id == $cart_item['product_id'] && isset( $cart_item[ $this->cart_item_key ] ) ) { - $is_purchasable = true; - break; - } - } - } elseif ( isset( $_GET['resubscribe'] ) ) { // Is a request to resubscribe - - $subscription = wcs_get_subscription( absint( $_GET['resubscribe'] ) ); - - if ( false !== $subscription && $subscription->has_product( $product->id ) && wcs_can_user_resubscribe_to( $subscription ) ) { - $is_purchasable = true; - } - } - } - - return $is_purchasable; } /** @@ -221,5 +225,93 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal { return $subscription; } + + /** + * Make sure that a resubscribe item's cart key is based on the end of the pre-paid term if the user already has a subscription that is pending-cancel, not the date calculated for the product. + * + * @since 2.1 + */ + public function get_recurring_cart_key( $cart_key, $cart_item ) { + $subscription = $this->get_order( $cart_item ); + if ( false !== $subscription && $subscription->has_status( 'pending-cancel' ) ) { + remove_filter( 'woocommerce_subscriptions_recurring_cart_key', array( &$this, 'get_recurring_cart_key' ), 10, 2 ); + $cart_key = WC_Subscriptions_Cart::get_recurring_cart_key( $cart_item, $subscription->get_time( 'end' ) ); + add_filter( 'woocommerce_subscriptions_recurring_cart_key', array( &$this, 'get_recurring_cart_key' ), 10, 2 ); + } + + return $cart_key; + } + + /** + * Make sure when displaying the next payment date for a subscription, the date takes into + * account the end of the pre-paid term if the user is resubscribing to a subscription that is pending-cancel. + * + * @since 2.1 + */ + public function recurring_cart_next_payment_date( $first_renewal_date, $cart ) { + foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { + $subscription = $this->get_order( $cart_item ); + if ( false !== $subscription && $subscription->has_status( 'pending-cancel' ) ) { + $first_renewal_date = ( '1' != $cart_item['data']->subscription_length ) ? $subscription->get_date( 'end' ) : 0; + break; + } + } + return $first_renewal_date; + } + + /** + * Make sure resubscribe cart item price doesn't include any recurring amount by setting a free trial. + * + * @since 2.1 + */ + public function maybe_set_free_trial( $total = '' ) { + + foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { + $subscription = $this->get_order( $cart_item ); + if ( false !== $subscription && $subscription->has_status( 'pending-cancel' ) ) { + WC()->cart->cart_contents[ $cart_item_key ]['data']->subscription_trial_length = 1; + break; + } + } + + return $total; + } + + /** + * Remove mock free trials from resubscribe cart items. + * + * @since 2.1 + */ + public function maybe_unset_free_trial( $total = '' ) { + + foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { + $subscription = $this->get_order( $cart_item ); + if ( false !== $subscription && $subscription->has_status( 'pending-cancel' ) ) { + WC()->cart->cart_contents[ $cart_item_key ]['data']->subscription_trial_length = 0; + break; + } + } + + return $total; + } + + /** + * When the user resubscribes to a subscription that is pending-cancel, cancel the existing subscription. + * + * @since 2.1 + */ + public function maybe_cancel_existing_subscription( $order_id, $old_order_status, $new_order_status ) { + if ( wcs_order_contains_subscription( $order_id ) && wcs_order_contains_resubscribe( $order_id ) ) { + $order_completed = in_array( $new_order_status, array( apply_filters( 'woocommerce_payment_complete_order_status', 'processing', $order_id ), 'processing', 'completed' ) ); + $order_needed_payment = in_array( $old_order_status, apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'on-hold', 'failed' ) ) ); + + foreach ( wcs_get_subscriptions_for_resubscribe_order( $order_id ) as $subscription ) { + if ( $subscription->has_status( 'pending-cancel' ) ) { + $cancel_note = sprintf( __( 'Customer resubscribed in order #%s', 'woocommerce-subscriptions' ), wc_get_order( $order_id )->get_order_number() ); + $subscription->update_status( 'cancelled', $cancel_note ); + } + } + } + } } new WCS_Cart_Resubscribe(); diff --git a/includes/class-wcs-cart-switch.php b/includes/class-wcs-cart-switch.php new file mode 100644 index 0000000..eaed1d1 --- /dev/null +++ b/includes/class-wcs-cart-switch.php @@ -0,0 +1,119 @@ +query_vars are set + add_action( 'template_redirect', array( &$this, 'maybe_setup_cart' ), 99 ); + } + + /** + * Add flag to payment url for failed/ pending switch orders. + * + * @since 2.1 + */ + public function get_checkout_payment_url( $pay_url, $order ) { + + if ( wcs_order_contains_switch( $order ) ) { + $switch_order_data = get_post_meta( $order->id, '_subscription_switch_data', true ); + + if ( ! empty( $switch_order_data ) ) { + $pay_url = add_query_arg( array( + 'subscription_switch' => 'true', + '_wcsnonce' => wp_create_nonce( 'wcs_switch_request' ), + ), $pay_url ); + } + } + + return $pay_url; + } + + /** + * Check if a payment is being made on a switch order from 'My Account'. If so, + * reconstruct the cart with the order contents. If the order item is part of a switch, load the necessary data + * into $_GET and $_POST to ensure the switch validation occurs and the switch cart item meta is correctly loaded. + * + * @since 2.1 + */ + public function maybe_setup_cart() { + + global $wp; + + if ( isset( $_GET['pay_for_order'] ) && isset( $_GET['key'] ) && isset( $wp->query_vars['order-pay'] ) && isset( $_GET['subscription_switch'] ) ) { + + // Pay for existing order + $order_key = $_GET['key']; + $order_id = ( isset( $wp->query_vars['order-pay'] ) ) ? $wp->query_vars['order-pay'] : absint( $_GET['order_id'] ); + $order = wc_get_order( $wp->query_vars['order-pay'] ); + + if ( $order->order_key == $order_key && $order->has_status( array( 'pending', 'failed' ) ) && wcs_order_contains_switch( $order ) ) { + WC()->cart->empty_cart( true ); + + $switch_order_data = get_post_meta( $order_id, '_subscription_switch_data', true ); + + foreach ( $order->get_items() as $item_id => $line_item ) { + + unset( $_GET['switch-subscription'] ); + unset( $_GET['item'] ); + + // check if this order item is for a switch + foreach ( $switch_order_data as $subscription_id => $switch_data ) { + if ( isset( $switch_data['switches'] ) && in_array( $item_id, array_keys( $switch_data['switches'] ) ) ) { + $_GET['switch-subscription'] = $subscription_id; + $_GET['item'] = $switch_data['switches'][ $item_id ]['subscription_item_id']; + break; + } + } + + $order_item = wcs_get_order_item( $item_id, $order ); + $product = WC_Subscriptions::get_product( wcs_get_canonical_product_id( $order_item ) ); + + $order_product_data = array( + '_qty' => 0, + '_variation_id' => '', + ); + + $variations = array(); + + foreach ( $order_item['item_meta'] as $meta_key => $meta_value ) { + + if ( taxonomy_is_product_attribute( $meta_key ) || meta_is_product_attribute( $meta_key, $meta_value[0], $product->id ) ) { + $variations[ $meta_key ] = $meta_value[0]; + $_POST[ 'attribute_' . $meta_key ] = $meta_value[0]; + } else if ( array_key_exists( $meta_key, $order_product_data ) ) { + $order_product_data[ $meta_key ] = (int) $meta_value[0]; + } + } + + $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product->id, $order_product_data['_qty'], $order_product_data['_variation_id'] ); + + if ( $passed_validation ) { + $cart_item_key = WC()->cart->add_to_cart( $product->id, $order_product_data['_qty'], $order_product_data['_variation_id'], $variations, array() ); + } + } + } + + WC()->session->set( 'order_awaiting_payment', $order_id ); + $this->set_cart_hash( $order_id ); + + wp_safe_redirect( WC()->cart->get_checkout_url() ); + exit; + } + } +} +new WCS_Cart_Switch(); diff --git a/includes/class-wcs-change-payment-method-admin.php b/includes/class-wcs-change-payment-method-admin.php index ec6e1c4..7bd8e95 100644 --- a/includes/class-wcs-change-payment-method-admin.php +++ b/includes/class-wcs-change-payment-method-admin.php @@ -49,7 +49,7 @@ class WCS_Change_Payment_Method_Admin { } elseif ( count( $valid_payment_methods ) == 1 ) { echo '' . esc_html__( 'Payment Method', 'woocommerce-subscriptions' ) . ':
' . esc_html( current( $valid_payment_methods ) ); - echo ''; + echo wcs_help_tip( sprintf( _x( 'Gateway ID: [%s]', 'The gateway ID displayed on the Edit Subscriptions screen when editing payment method.', 'woocommerce-subscriptions' ), key( $valid_payment_methods ) ) ); echo ''; } diff --git a/includes/class-wcs-limiter.php b/includes/class-wcs-limiter.php new file mode 100644 index 0000000..e6249bc --- /dev/null +++ b/includes/class-wcs-limiter.php @@ -0,0 +1,241 @@ +'; + echo '
'; + + // Only one Subscription per customer + woocommerce_wp_select( array( + 'id' => '_subscription_limit', + 'label' => __( 'Limit subscription', 'woocommerce-subscriptions' ), + // translators: placeholders are opening and closing link tags + 'description' => sprintf( __( 'Only allow a customer to have one subscription to this product. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), + 'options' => array( + 'no' => __( 'Do not limit', 'woocommerce-subscriptions' ), + 'active' => __( 'Limit to one active subscription', 'woocommerce-subscriptions' ), + 'any' => __( 'Limit to one of any status', 'woocommerce-subscriptions' ), + ), + ) ); + + do_action( 'woocommerce_subscriptions_product_options_advanced' ); + } + + /** + * Canonical is_purchasable method to be called by product classes. + * + * @since 2.1 + * @param bool $purchasable Whether the product is purchasable as determined by parent class + * @param mixed $product The product in question to be checked if it is purchasable. + * @param string $product_class Determines the subscription type of the product. Controls switch logic. + * + * @return bool + */ + public static function is_purchasable( $purchasable, $product ) { + switch ( $product->get_type() ) { + case 'subscription' : + case 'variable-subscription' : + if ( true === $purchasable && false === self::is_purchasable_product( $purchasable, $product ) ) { + $purchasable = false; + } + break; + case 'subscription_variation' : + if ( 'no' != wcs_get_product_limitation( $product->parent ) && ! empty( WC()->cart->cart_contents ) && ! wcs_is_order_received_page() && ! wcs_is_paypal_api_page() ) { + foreach ( WC()->cart->cart_contents as $cart_item ) { + if ( $product->id == $cart_item['data']->id && $product->variation_id != $cart_item['data']->variation_id ) { + $purchasable = false; + break; + } + } + } + break; + } + return $purchasable; + } + + + /** + * If a product is limited and the customer already has a subscription, mark it as not purchasable. + * + * @since 2.1 Moved from WC_Subscriptions_Product + * @return bool + */ + public static function is_purchasable_product( $is_purchasable, $product ) { + + //Set up cache + if ( ! isset( self::$is_purchasable_cache[ $product->id ] ) ) { + self::$is_purchasable_cache[ $product->id ] = array(); + } + + if ( ! isset( self::$is_purchasable_cache[ $product->id ]['standard'] ) ) { + self::$is_purchasable_cache[ $product->id ]['standard'] = $is_purchasable; + + if ( WC_Subscriptions_Product::is_subscription( $product->id ) && 'no' != wcs_get_product_limitation( $product ) && ! wcs_is_order_received_page() && ! wcs_is_paypal_api_page() ) { + + if ( wcs_is_product_limited_for_user( $product ) && ! self::order_awaiting_payment_for_product( $product->id ) ) { + self::$is_purchasable_cache[ $product->id ]['standard'] = false; + } + } + } + return self::$is_purchasable_cache[ $product->id ]['standard']; + + } + + /** + * If a product is being marked as not purchasable because it is limited and the customer has a subscription, + * but the current request is to switch the subscription, then mark it as purchasable. + * + * @since 2.1 Moved from WC_Subscriptions_Switcher::is_purchasable + * @return bool + */ + public static function is_purchasable_switch( $is_purchasable, $product ) { + $product_key = wcs_get_canonical_product_id( $product ); + + if ( ! isset( self::$is_purchasable_cache[ $product_key ] ) ) { + self::$is_purchasable_cache[ $product_key ] = array(); + } + + if ( ! isset( self::$is_purchasable_cache[ $product_key ]['switch'] ) ) { + + if ( false === $is_purchasable && wcs_is_product_switchable_type( $product ) && WC_Subscriptions_Product::is_subscription( $product->id ) && 'no' != wcs_get_product_limitation( $product ) && is_user_logged_in() && wcs_user_has_subscription( 0, $product->id, wcs_get_product_limitation( $product ) ) ) { + + //Adding to cart + if ( isset( $_GET['switch-subscription'] ) ) { + $is_purchasable = true; + + //Validating when restring cart from session + } elseif ( WC_Subscriptions_Switcher::cart_contains_switches() ) { + $is_purchasable = true; + + // Restoring cart from session, so need to check the cart in the session (WC_Subscriptions_Switcher::cart_contains_subscription_switch() only checks the cart) + } elseif ( isset( WC()->session->cart ) ) { + + foreach ( WC()->session->cart as $cart_item_key => $cart_item ) { + if ( $product->id == $cart_item['product_id'] && isset( $cart_item['subscription_switch'] ) ) { + $is_purchasable = true; + break; + } + } + } + } + self::$is_purchasable_cache[ $product_key ]['switch'] = $is_purchasable; + } + return self::$is_purchasable_cache[ $product_key ]['switch']; + } + + /** + * Determines whether a product is purchasable based on whether the cart is to resubscribe or renew. + * + * @since 2.1 Combines WCS_Cart_Renewal::is_purchasable and WCS_Cart_Resubscribe::is_purchasable + * @return bool + */ + public static function is_purchasable_renewal( $is_purchasable, $product ) { + if ( false === $is_purchasable && false === self::is_purchasable_product( $is_purchasable, $product ) ) { + + // Resubscribe logic + if ( isset( $_GET['resubscribe'] ) || false !== ( $resubscribe_cart_item = wcs_cart_contains_resubscribe() ) ) { + $subscription_id = ( isset( $_GET['resubscribe'] ) ) ? absint( $_GET['resubscribe'] ) : $resubscribe_cart_item['subscription_resubscribe']['subscription_id']; + $subscription = wcs_get_subscription( $subscription_id ); + + if ( false != $subscription && $subscription->has_product( $product->id ) && wcs_can_user_resubscribe_to( $subscription ) ) { + $is_purchasable = true; + } + + // Renewal logic + } elseif ( isset( $_GET['subscription_renewal'] ) || wcs_cart_contains_renewal() ) { + $is_purchasable = true; + + // Restoring cart from session, so need to check the cart in the session (wcs_cart_contains_renewal() only checks the cart) + } elseif ( WC()->session->cart ) { + foreach ( WC()->session->cart as $cart_item_key => $cart_item ) { + if ( $product->id == $cart_item['product_id'] && ( isset( $cart_item['subscription_renewal'] ) || isset( $cart_item['subscription_resubscribe'] ) ) ) { + $is_purchasable = true; + break; + } + } + } + } + return $is_purchasable; + } + + /** + * Check if the current session has an order awaiting payment for a subscription to a specific product line item. + * + * @since 2.1 Moved from WC_Subscriptions_Product + * @return bool + **/ + protected static function order_awaiting_payment_for_product( $product_id ) { + global $wp; + + if ( ! isset( self::$order_awaiting_payment_for_product[ $product_id ] ) ) { + + self::$order_awaiting_payment_for_product[ $product_id ] = false; + + if ( ! empty( WC()->session->order_awaiting_payment ) || isset( $_GET['pay_for_order'] ) ) { + + $order_id = ! empty( WC()->session->order_awaiting_payment ) ? WC()->session->order_awaiting_payment : $wp->query_vars['order-pay']; + $order = wc_get_order( absint( $order_id ) ); + + if ( is_object( $order ) && $order->has_status( array( 'pending', 'failed' ) ) ) { + foreach ( $order->get_items() as $item ) { + if ( $item['product_id'] == $product_id || $item['variation_id'] == $product_id ) { + + $subscriptions = wcs_get_subscriptions( array( + 'order_id' => $order->id, + 'product_id' => $product_id, + ) ); + + if ( ! empty( $subscriptions ) ) { + $subscription = array_pop( $subscriptions ); + + if ( $subscription->has_status( array( 'pending', 'on-hold' ) ) ) { + self::$order_awaiting_payment_for_product[ $product_id ] = true; + } + } + break; + } + } + } + } + } + + return self::$order_awaiting_payment_for_product[ $product_id ]; + } + +} +WCS_Limiter::init(); diff --git a/includes/class-wcs-query.php b/includes/class-wcs-query.php index cb6141d..ad6bd5d 100644 --- a/includes/class-wcs-query.php +++ b/includes/class-wcs-query.php @@ -66,6 +66,9 @@ class WCS_Query extends WC_Query { foreach ( $this->query_vars as $key => $query_var ) { if ( $this->is_query( $query_var ) ) { $title = $this->get_endpoint_title( $key ); + + // unhook after we've returned our title to prevent it from overriding others + remove_filter( 'the_title', array( $this, __FUNCTION__ ), 11 ); } } } diff --git a/includes/class-wcs-retry-manager.php b/includes/class-wcs-retry-manager.php new file mode 100644 index 0000000..5a9d7f4 --- /dev/null +++ b/includes/class-wcs-retry-manager.php @@ -0,0 +1,321 @@ +get_date( 'payment_retry' ) > 0 ) { + + $last_order = $subscription->get_last_order( 'all' ); + $last_retry = ( $last_order ) ? self::store()->get_last_retry_for_order( $last_order->id ) : null; + + if ( null !== $last_retry && 'cancelled' !== $last_retry->get_status() && null !== ( $last_retry_rule = $last_retry->get_rule() ) ) { + + $retry_subscription_status = $last_retry_rule->get_status_to_apply( 'subscription' ); + $applying_retry_rule = did_action( 'woocommerce_subscriptions_before_apply_retry_rule' ) !== did_action( 'woocommerce_subscriptions_after_apply_retry_rule' ); + $retrying_payment = did_action( 'woocommerce_subscriptions_before_payment_retry' ) !== did_action( 'woocommerce_subscriptions_after_payment_retry' ); + + // If the new status isn't the expected retry subscription status and we aren't in the process of applying a retry rule or retrying payment, cancel the retry + if ( $new_status != $retry_subscription_status && ! $applying_retry_rule && ! $retrying_payment ) { + $last_retry->update_status( 'cancelled' ); + } + } + } + } + + /** + * When a retry's status is updated, if it's no longer pending or processing and it's the most recent retry, + * delete the retry date on the subscriptions related to the order + * + * @param object $retry An instance of a WCS_Retry object + * @param string $new_status A valid retry status + */ + public static function maybe_delete_payment_retry_date( $retry, $new_status ) { + if ( ! in_array( $new_status, array( 'pending', 'processing' ) ) ) { + + $last_retry = self::store()->get_last_retry_for_order( $retry->get_order_id() ); + + if ( $retry->get_id() === $last_retry->get_id() ) { + foreach ( wcs_get_subscriptions_for_renewal_order( $retry->get_order_id() ) as $subscription ) { + $subscription->delete_date( 'payment_retry' ); + } + } + } + + } + + /** + * When a payment fails, apply a retry rule, if one exists that applies to this failure. + * + * @param WC_Subscription The subscription on which the payment failed + * @param WC_Order The order on which the payment failed (will be the most recent order on the subscription specified with the subscription param) + * @since 2.1 + */ + public static function maybe_apply_retry_rule( $subscription, $last_order ) { + + if ( $subscription->is_manual() || ! $subscription->payment_method_supports( 'subscription_date_changes' ) ) { + return; + } + + $retry_count = self::store()->get_retry_count_for_order( $last_order->id ); + + if ( self::rules()->has_rule( $retry_count, $last_order->id ) ) { + + $retry_rule = self::rules()->get_rule( $retry_count, $last_order->id ); + + do_action( 'woocommerce_subscriptions_before_apply_retry_rule', $retry_rule, $last_order, $subscription ); + + $retry_id = self::store()->save( new WCS_Retry( array( + 'status' => 'pending', + 'order_id' => $last_order->id, + 'date_gmt' => gmdate( 'Y-m-d H:i:s', gmdate( 'U' ) + $retry_rule->get_retry_interval() ), + 'rule_raw' => $retry_rule->get_raw_data(), + ) ) ); + + foreach ( array( 'order' => $last_order, 'subscription' => $subscription ) as $object_key => $object ) { + + $new_status = $retry_rule->get_status_to_apply( $object_key ); + + if ( '' !== $new_status && ! $object->has_status( $new_status ) ) { + $object->update_status( $new_status, _x( 'Retry rule applied:', 'used in order note as reason for why status changed', 'woocommerce-subscriptions' ) ); + } + } + + if ( $retry_rule->get_retry_interval() > 0 ) { + // by calling this after changing the status, this will also schedule the 'woocommerce_scheduled_subscription_payment_retry' action + $subscription->update_dates( array( 'payment_retry' => gmdate( 'Y-m-d H:i:s', gmdate( 'U' ) + $retry_rule->get_retry_interval( $retry_count ) ) ) ); + } + + do_action( 'woocommerce_subscriptions_after_apply_retry_rule', $retry_rule, $last_order, $subscription ); + } + } + + /** + * When a retry hook is triggered, check if the rules for that retry are still valid + * and if so, retry the payment. + * + * @param WC_Order|int The order on which the payment failed + * @since 2.1 + */ + public static function maybe_retry_payment( $last_order ) { + + if ( ! is_object( $last_order ) ) { + $last_order = wc_get_order( $last_order ); + } + + if ( false === $last_order ) { + return; + } + + $subscriptions = wcs_get_subscriptions_for_renewal_order( $last_order ); + $last_retry = self::store()->get_last_retry_for_order( $last_order->id ); + + // we only need to retry the payment if we have applied a retry rule for the order and it still needs payment + if ( null !== $last_retry && 'pending' === $last_retry->get_status() ) { + + do_action( 'woocommerce_subscriptions_before_payment_retry', $last_retry, $last_order ); + + if ( $last_order->needs_payment() ) { + + $last_retry->update_status( 'processing' ); + + $expected_order_status = $last_retry->get_rule()->get_status_to_apply( 'order' ); + $valid_order_status = ( '' == $expected_order_status || $last_order->has_status( $expected_order_status ) ) ? true : false; + + $expected_subscription_status = $last_retry->get_rule()->get_status_to_apply( 'subscription' ); + + if ( '' == $expected_subscription_status ) { + + $valid_subscription_status = true; + + } else { + + $valid_subscription_status = true; + + foreach ( $subscriptions as $subscription ) { + if ( ! $subscription->has_status( $expected_subscription_status ) ) { + $valid_subscription_status = false; + break; + } + } + } + + // if both statuses are still the same or there no special status was applied and the order still needs payment (i.e. there has been no manual intervention), trigger the payment hook + if ( $valid_order_status && $valid_subscription_status ) { + + // Make sure the subscription is on hold in case something goes wrong while trying to process renewal and in case gateways expect the subscription to be on-hold, which is normally the case with a renewal payment + foreach ( $subscriptions as $subscription ) { + $subscription->update_status( 'on-hold', _x( 'Subscription renewal payment retry:', 'used in order note as reason for why subscription status changed', 'woocommerce-subscriptions' ) ); + } + + WC_Subscriptions_Payment_Gateways::trigger_gateway_renewal_payment_hook( $last_order ); + + // Now that we've attempted to process the payment, refresh the order + $last_order = wc_get_order( $last_order->id ); + + // if the order still needs payment, payment failed + if ( $last_order->needs_payment() ) { + $last_retry->update_status( 'failed' ); + } else { + $last_retry->update_status( 'complete' ); + } + } else { + // order or subscription statuses have been manually updated, so we'll cancel the retry + $last_retry->update_status( 'cancelled' ); + } + } else { + // last order must have been paid for some other way, so we'll cancel the retry + $last_retry->update_status( 'cancelled' ); + } + + do_action( 'woocommerce_subscriptions_after_payment_retry', $last_retry, $last_order ); + } + } + + /** + * Access the object used to interface with the database + * + * @since 2.1 + */ + public static function store() { + if ( empty( self::$store ) ) { + $class = self::get_store_class(); + self::$store = new $class(); + } + return self::$store; + } + + /** + * Get the class used for instantiating retry storage via self::store() + * + * @since 2.1 + */ + protected static function get_store_class() { + return apply_filters( 'wcs_retry_store_class', 'WCS_Retry_Post_Store' ); + } + + /** + * Setup and access the object used to interface with retry rules + * + * @since 2.1 + */ + public static function rules() { + if ( empty( self::$retry_rules ) ) { + $class = self::get_rules_class(); + self::$retry_rules = new $class(); + } + return self::$retry_rules; + } + + /** + * Get the class used for instantiating retry rules via self::rules() + * + * @since 2.1 + */ + protected static function get_rules_class() { + return apply_filters( 'wcs_retry_rules_class', 'WCS_Retry_Rules' ); + } +} +WCS_Retry_Manager::init(); diff --git a/includes/class-wcs-webhooks.php b/includes/class-wcs-webhooks.php index eccdc01..132ce51 100644 --- a/includes/class-wcs-webhooks.php +++ b/includes/class-wcs-webhooks.php @@ -32,10 +32,14 @@ class WCS_Webhooks { add_filter( 'woocommerce_valid_webhook_resources', __CLASS__ . '::add_resource', 10, 1 ); + add_filter( 'woocommerce_valid_webhook_events', __CLASS__ . '::add_event', 10, 1 ); + add_action( 'woocommerce_checkout_subscription_created', __CLASS__ . '::add_subscription_created_callback', 10, 1 ); add_action( 'woocommerce_subscription_date_updated', __CLASS__ . '::add_subscription_updated_callback', 10, 1 ); + add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::add_subscription_switched_callback', 10, 1 ); + add_filter( 'woocommerce_webhook_topics' , __CLASS__ . '::add_topics_admin_menu', 10, 1 ); } @@ -66,6 +70,9 @@ class WCS_Webhooks { 'woocommerce_subscription_deleted', 'woocommerce_api_delete_subscription', ), + 'subscription.switched' => array( + 'wcs_webhook_subscription_switched', + ), ), $webhook ); } @@ -80,9 +87,10 @@ class WCS_Webhooks { public static function add_topics_admin_menu( $topics ) { $front_end_topics = array( - 'subscription.created' => __( ' Subscription Created', 'woocommerce-subscriptions' ), - 'subscription.updated' => __( ' Subscription Updated', 'woocommerce-subscriptions' ), - 'subscription.deleted' => __( ' Subscription Deleted', 'woocommerce-subscriptions' ), + 'subscription.created' => __( ' Subscription Created', 'woocommerce-subscriptions' ), + 'subscription.updated' => __( ' Subscription Updated', 'woocommerce-subscriptions' ), + 'subscription.deleted' => __( ' Subscription Deleted', 'woocommerce-subscriptions' ), + 'subscription.switched' => __( ' Subscription Switched', 'woocommerce-subscriptions' ), ); return array_merge( $topics, $front_end_topics ); @@ -126,6 +134,19 @@ class WCS_Webhooks { return $resources; } + /** + * Add webhook event for subscription switched. + * + * @param array $events + * @since 2.1 + */ + public static function add_event( $events ) { + + $events[] = 'switched'; + + return $events; + } + /** * Call a "subscription created" action hook with the first parameter being a subscription id so that it can be used * for webhooks. @@ -145,5 +166,17 @@ class WCS_Webhooks { do_action( 'wcs_webhook_subscription_updated', $subscription->id ); } + /** + * For each switched subscription in an order, call a "subscription switched" action hook with a subscription id as the first parameter to be used for webhooks payloads. + * + * @since 2.1 + */ + public static function add_subscription_switched_callback( $order ) { + $switched_subscriptions = wcs_get_subscriptions_for_switch_order( $order ); + foreach ( array_keys( $switched_subscriptions ) as $subscription_id ) { + do_action( 'wcs_webhook_subscription_switched', $subscription_id ); + } + } + } WCS_Webhooks::init(); diff --git a/includes/emails/class-wcs-email-cancelled-subscription.php b/includes/emails/class-wcs-email-cancelled-subscription.php index 6edf483..283407f 100644 --- a/includes/emails/class-wcs-email-cancelled-subscription.php +++ b/includes/emails/class-wcs-email-cancelled-subscription.php @@ -8,9 +8,9 @@ if ( ! defined( 'ABSPATH' ) ) { * An email sent to the admin when a subscription is cancelled (either by a store manager, or the customer). * * @class WCS_Email_Cancelled_Subscription - * @version 1.4 + * @version 2.1 * @package WooCommerce_Subscriptions/Classes/Emails - * @author Brent Shepherd + * @author Prospress * @extends WC_Email */ class WCS_Email_Cancelled_Subscription extends WC_Email { @@ -79,8 +79,11 @@ class WCS_Email_Cancelled_Subscription extends WC_Email { wc_get_template( $this->template_html, array( - 'subscription' => $this->object, - 'email_heading' => $this->get_heading(), + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -99,8 +102,11 @@ class WCS_Email_Cancelled_Subscription extends WC_Email { wc_get_template( $this->template_plain, array( - 'subscription' => $this->object, - 'email_heading' => $this->get_heading(), + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-customer-completed-renewal-order.php b/includes/emails/class-wcs-email-customer-completed-renewal-order.php index 6aa9e75..8ea9fc0 100644 --- a/includes/emails/class-wcs-email-customer-completed-renewal-order.php +++ b/includes/emails/class-wcs-email-customer-completed-renewal-order.php @@ -64,9 +64,9 @@ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Orde $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -118,6 +118,9 @@ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Orde array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -138,6 +141,9 @@ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Orde array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-customer-completed-switch-order.php b/includes/emails/class-wcs-email-customer-completed-switch-order.php index ab083b8..3b7b95a 100644 --- a/includes/emails/class-wcs-email-customer-completed-switch-order.php +++ b/includes/emails/class-wcs-email-customer-completed-switch-order.php @@ -63,9 +63,9 @@ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -120,6 +120,9 @@ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order 'order' => $this->object, 'subscriptions' => $this->subscriptions, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -141,6 +144,9 @@ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order 'order' => $this->object, 'subscriptions' => $this->subscriptions, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-customer-payment-retry.php b/includes/emails/class-wcs-email-customer-payment-retry.php new file mode 100644 index 0000000..f98391e --- /dev/null +++ b/includes/emails/class-wcs-email-customer-payment-retry.php @@ -0,0 +1,134 @@ +id = 'customer_payment_retry'; + $this->title = __( 'Customer Payment Retry', 'woocommerce-subscriptions' ); + $this->description = __( 'Sent to a customer when an attempt to automatically process a subscription renewal payment has failed and a retry rule has been applied to retry the payment in the future. The email contains the renewal order information, date of the scheduled retry and payment links to allow the customer to pay for the renewal order manually instead of waiting for the automatic retry.', 'woocommerce-subscriptions' ); + $this->customer_email = true; + + $this->template_html = 'emails/customer-payment-retry.php'; + $this->template_plain = 'emails/plain/customer-payment-retry.php'; + $this->template_base = plugin_dir_path( WC_Subscriptions::$plugin_file ) . 'templates/'; + + $this->subject = __( 'Automatic payment failed for {order_number}, we will retry {retry_time}', 'woocommerce-subscriptions' ); + $this->heading = __( 'Automatic payment failed for order {order_number}', 'woocommerce-subscriptions' ); + + // We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor + WC_Email::__construct(); + } + + /** + * trigger function. + * + * We can use most of WCS_Email_Customer_Renewal_Invoice's trigger method but we need to set up the + * retry data ourselves before calling it as WCS_Email_Customer_Renewal_Invoice has no retry + * associated with it. + * + * @access public + * @return void + */ + function trigger( $order ) { + + $this->retry = WCS_Retry_Manager::store()->get_last_retry_for_order( $order->id ); + + $retry_time_index = array_search( '{retry_time}', $this->find ); + if ( false === $retry_time_index ) { + $this->find[] = '{retry_time}'; + $this->replace[] = strtolower( wcs_get_human_time_diff( $this->retry->get_time() ) ); + } else { + $this->replace[ $retry_time_index ] = strtolower( wcs_get_human_time_diff( $this->retry->get_time() ) ); + } + + parent::trigger( $order ); + } + + /** + * get_subject function. + * + * @access public + * @return string + */ + function get_subject() { + return apply_filters( 'woocommerce_subscriptions_email_subject_customer_retry', parent::get_subject(), $this->object ); + } + + /** + * get_heading function. + * + * @access public + * @return string + */ + function get_heading() { + return apply_filters( 'woocommerce_email_heading_customer_retry', parent::get_heading(), $this->object ); + } + + /** + * get_content_html function. + * + * @access public + * @return string + */ + function get_content_html() { + ob_start(); + wc_get_template( + $this->template_html, + array( + 'order' => $this->object, + 'retry' => $this->retry, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } + + /** + * get_content_plain function. + * + * @access public + * @return string + */ + function get_content_plain() { + ob_start(); + wc_get_template( + $this->template_plain, + array( + 'order' => $this->object, + 'retry' => $this->retry, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } +} diff --git a/includes/emails/class-wcs-email-customer-processing-renewal-order.php b/includes/emails/class-wcs-email-customer-processing-renewal-order.php index e4829b3..e97c2db 100644 --- a/includes/emails/class-wcs-email-customer-processing-renewal-order.php +++ b/includes/emails/class-wcs-email-customer-processing-renewal-order.php @@ -58,9 +58,9 @@ class WCS_Email_Processing_Renewal_Order extends WC_Email_Customer_Processing_Or $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -112,6 +112,9 @@ class WCS_Email_Processing_Renewal_Order extends WC_Email_Customer_Processing_Or array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -132,6 +135,9 @@ class WCS_Email_Processing_Renewal_Order extends WC_Email_Customer_Processing_Or array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-customer-renewal-invoice.php b/includes/emails/class-wcs-email-customer-renewal-invoice.php index 4dad736..2c4cdc3 100644 --- a/includes/emails/class-wcs-email-customer-renewal-invoice.php +++ b/includes/emails/class-wcs-email-customer-renewal-invoice.php @@ -7,17 +7,21 @@ if ( ! defined( 'ABSPATH' ) ) { * * An email sent to the customer via admin. * - * @class WC_Email_Customer_Invoice - * @version 2.0.0 - * @package WooCommerce/Classes/Emails - * @author WooThemes - * @extends WC_Email + * @class WCS_Email_Customer_Renewal_Invoice + * @version 1.4 + * @package WooCommerce_Subscriptions/Includes/Emails + * @author Prospress + * @extends WC_Email_Customer_Invoice */ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { var $find; var $replace; + // fields used in WC_Email_Customer_Invoice this class doesn't need + var $subject_paid = null; + var $heading_paid = null; + /** * Constructor */ @@ -25,7 +29,7 @@ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { $this->id = 'customer_renewal_invoice'; $this->title = __( 'Customer Renewal Invoice', 'woocommerce-subscriptions' ); - $this->description = __( 'Sent to a customer when the subscription is due for renewal and the renewal requires a manual payment, either because it uses manual renewals or the automatic recurring payment failed. The email contains renewal order information and payment links.', 'woocommerce-subscriptions' ); + $this->description = __( 'Sent to a customer when the subscription is due for renewal and the renewal requires a manual payment, either because it uses manual renewals or the automatic recurring payment failed for the initial attempt and all automatic retries (if any). The email contains renewal order information and payment links.', 'woocommerce-subscriptions' ); $this->customer_email = true; $this->template_html = 'emails/customer-renewal-invoice.php'; @@ -35,9 +39,6 @@ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { $this->subject = __( 'Invoice for renewal order {order_number} from {order_date}', 'woocommerce-subscriptions' ); $this->heading = __( 'Invoice for renewal order {order_number}', 'woocommerce-subscriptions' ); - $this->subject_paid = null; - $this->heading_paid = null; - // Triggers for this email add_action( 'woocommerce_generated_manual_renewal_order_renewal_notification', array( $this, 'trigger' ) ); add_action( 'woocommerce_order_status_failed_renewal_notification', array( $this, 'trigger' ) ); @@ -68,9 +69,9 @@ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -122,6 +123,9 @@ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -142,6 +146,9 @@ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => false, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-expired-subscription.php b/includes/emails/class-wcs-email-expired-subscription.php new file mode 100644 index 0000000..47cecfe --- /dev/null +++ b/includes/emails/class-wcs-email-expired-subscription.php @@ -0,0 +1,165 @@ +id = 'expired_subscription'; + $this->title = __( 'Expired Subscription', 'woocommerce-subscriptions' ); + $this->description = __( 'Expired Subscription emails are sent when a customer\'s subscription expires.', 'woocommerce-subscriptions' ); + + $this->heading = __( 'Subscription Expired', 'woocommerce-subscriptions' ); + // translators: placeholder is {blogname}, a variable that will be substituted when email is sent out + $this->subject = sprintf( _x( '[%s] Subscription Expired', 'default email subject for expired emails sent to the admin', 'woocommerce-subscriptions' ), '{blogname}' ); + + $this->template_html = 'emails/expired-subscription.php'; + $this->template_plain = 'emails/plain/expired-subscription.php'; + $this->template_base = plugin_dir_path( WC_Subscriptions::$plugin_file ) . 'templates/'; + + add_action( 'expired_subscription_notification', array( $this, 'trigger' ) ); + + parent::__construct(); + + $this->recipient = $this->get_option( 'recipient' ); + + if ( ! $this->recipient ) { + $this->recipient = get_option( 'admin_email' ); + } + } + + /** + * trigger function. + * + * @access public + * @return void + */ + function trigger( $subscription ) { + $this->object = $subscription; + + if ( ! is_object( $subscription ) ) { + throw new InvalidArgumentException( __( 'Subscription argument passed in is not an object.', 'woocommerce-subscriptions' ) ); + } + + if ( ! $this->is_enabled() || ! $this->get_recipient() ) { + return; + } + + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + /** + * get_content_html function. + * + * @access public + * @return string + */ + function get_content_html() { + ob_start(); + wc_get_template( + $this->template_html, + array( + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } + + /** + * get_content_plain function. + * + * @access public + * @return string + */ + function get_content_plain() { + ob_start(); + wc_get_template( + $this->template_plain, + array( + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } + + /** + * Initialise Settings Form Fields + * + * @access public + * @return void + */ + function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => _x( 'Enable/Disable', 'an email notification', 'woocommerce-subscriptions' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce-subscriptions' ), + 'default' => 'no', + ), + 'recipient' => array( + 'title' => _x( 'Recipient(s)', 'of an email', 'woocommerce-subscriptions' ), + 'type' => 'text', + // translators: placeholder is admin email + 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s.', 'woocommerce-subscriptions' ), esc_attr( get_option( 'admin_email' ) ) ), + 'placeholder' => '', + 'default' => '', + ), + 'subject' => array( + 'title' => _x( 'Subject', 'of an email', 'woocommerce-subscriptions' ), + 'type' => 'text', + 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: %s.', 'woocommerce-subscriptions' ), $this->subject ), + 'placeholder' => '', + 'default' => '', + ), + 'heading' => array( + 'title' => _x( 'Email Heading', 'Name the setting that controls the main heading contained within the email notification', 'woocommerce-subscriptions' ), + 'type' => 'text', + 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: %s.', 'woocommerce-subscriptions' ), $this->heading ), + 'placeholder' => '', + 'default' => '', + ), + 'email_type' => array( + 'title' => _x( 'Email type', 'text, html or multipart', 'woocommerce-subscriptions' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ), + 'default' => 'html', + 'class' => 'email_type', + 'options' => array( + 'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ), + 'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ), + 'multipart' => _x( 'Multipart', 'email type', 'woocommerce-subscriptions' ), + ), + ), + ); + } +} diff --git a/includes/emails/class-wcs-email-new-renewal-order.php b/includes/emails/class-wcs-email-new-renewal-order.php index 100ac68..2a7d2eb 100644 --- a/includes/emails/class-wcs-email-new-renewal-order.php +++ b/includes/emails/class-wcs-email-new-renewal-order.php @@ -65,9 +65,9 @@ class WCS_Email_New_Renewal_Order extends WC_Email_New_Order { $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -99,6 +99,9 @@ class WCS_Email_New_Renewal_Order extends WC_Email_New_Order { array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -119,6 +122,9 @@ class WCS_Email_New_Renewal_Order extends WC_Email_New_Order { array( 'order' => $this->object, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-new-switch-order.php b/includes/emails/class-wcs-email-new-switch-order.php index 1156d98..4e8c1a5 100644 --- a/includes/emails/class-wcs-email-new-switch-order.php +++ b/includes/emails/class-wcs-email-new-switch-order.php @@ -65,9 +65,9 @@ class WCS_Email_New_Switch_Order extends WC_Email_New_Order { $order_date_index = array_search( '{order_date}', $this->find ); if ( false === $order_date_index ) { $this->find[] = '{order_date}'; - $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } else { - $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace[ $order_date_index ] = date_i18n( wc_date_format(), wcs_date_to_time( $this->object->order_date ) ); } $order_number_index = array_search( '{order_number}', $this->find ); @@ -102,6 +102,9 @@ class WCS_Email_New_Switch_Order extends WC_Email_New_Order { 'order' => $this->object, 'subscriptions' => $this->subscriptions, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, ), '', $this->template_base @@ -123,6 +126,9 @@ class WCS_Email_New_Switch_Order extends WC_Email_New_Order { 'order' => $this->object, 'subscriptions' => $this->subscriptions, 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, ), '', $this->template_base diff --git a/includes/emails/class-wcs-email-on-hold-subscription.php b/includes/emails/class-wcs-email-on-hold-subscription.php new file mode 100644 index 0000000..26bf84d --- /dev/null +++ b/includes/emails/class-wcs-email-on-hold-subscription.php @@ -0,0 +1,165 @@ +id = 'suspended_subscription'; + $this->title = __( 'Suspended Subscription', 'woocommerce-subscriptions' ); + $this->description = __( 'Suspended Subscription emails are sent when a customer manually suspends their subscription.', 'woocommerce-subscriptions' ); + + $this->heading = __( 'Subscription Suspended', 'woocommerce-subscriptions' ); + // translators: placeholder is {blogname}, a variable that will be substituted when email is sent out + $this->subject = sprintf( _x( '[%s] Subscription Suspended', 'default email subject for suspended emails sent to the admin', 'woocommerce-subscriptions' ), '{blogname}' ); + + $this->template_html = 'emails/on-hold-subscription.php'; + $this->template_plain = 'emails/plain/on-hold-subscription.php'; + $this->template_base = plugin_dir_path( WC_Subscriptions::$plugin_file ) . 'templates/'; + + add_action( 'on-hold_subscription_notification', array( $this, 'trigger' ) ); + + parent::__construct(); + + $this->recipient = $this->get_option( 'recipient' ); + + if ( ! $this->recipient ) { + $this->recipient = get_option( 'admin_email' ); + } + } + + /** + * trigger function. + * + * @access public + * @return void + */ + function trigger( $subscription ) { + $this->object = $subscription; + + if ( ! is_object( $subscription ) ) { + throw new InvalidArgumentException( __( 'Subscription argument passed in is not an object.', 'woocommerce-subscriptions' ) ); + } + + if ( ! $this->is_enabled() || ! $this->get_recipient() ) { + return; + } + + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + /** + * get_content_html function. + * + * @access public + * @return string + */ + function get_content_html() { + ob_start(); + wc_get_template( + $this->template_html, + array( + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } + + /** + * get_content_plain function. + * + * @access public + * @return string + */ + function get_content_plain() { + ob_start(); + wc_get_template( + $this->template_plain, + array( + 'subscription' => $this->object, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ), + '', + $this->template_base + ); + return ob_get_clean(); + } + + /** + * Initialise Settings Form Fields + * + * @access public + * @return void + */ + function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => _x( 'Enable/Disable', 'an email notification', 'woocommerce-subscriptions' ), + 'type' => 'checkbox', + 'label' => __( 'Enable this email notification', 'woocommerce-subscriptions' ), + 'default' => 'no', + ), + 'recipient' => array( + 'title' => _x( 'Recipient(s)', 'of an email', 'woocommerce-subscriptions' ), + 'type' => 'text', + // translators: placeholder is admin email + 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s.', 'woocommerce-subscriptions' ), esc_attr( get_option( 'admin_email' ) ) ), + 'placeholder' => '', + 'default' => '', + ), + 'subject' => array( + 'title' => _x( 'Subject', 'of an email', 'woocommerce-subscriptions' ), + 'type' => 'text', + 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: %s.', 'woocommerce-subscriptions' ), $this->subject ), + 'placeholder' => '', + 'default' => '', + ), + 'heading' => array( + 'title' => _x( 'Email Heading', 'Name the setting that controls the main heading contained within the email notification', 'woocommerce-subscriptions' ), + 'type' => 'text', + 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: %s.', 'woocommerce-subscriptions' ), $this->heading ), + 'placeholder' => '', + 'default' => '', + ), + 'email_type' => array( + 'title' => _x( 'Email type', 'text, html or multipart', 'woocommerce-subscriptions' ), + 'type' => 'select', + 'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ), + 'default' => 'html', + 'class' => 'email_type', + 'options' => array( + 'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ), + 'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ), + 'multipart' => _x( 'Multipart', 'email type', 'woocommerce-subscriptions' ), + ), + ), + ); + } +} diff --git a/includes/emails/class-wcs-email-payment-retry.php b/includes/emails/class-wcs-email-payment-retry.php new file mode 100644 index 0000000..65bfbe7 --- /dev/null +++ b/includes/emails/class-wcs-email-payment-retry.php @@ -0,0 +1,107 @@ +id = 'payment_retry'; + $this->title = __( 'Payment Retry', 'woocommerce-subscriptions' ); + $this->description = __( 'Payment retry emails are sent to chosen recipient(s) when an attempt to automatically process a subscription renewal payment has failed and a retry rule has been applied to retry the payment in the future.', 'woocommerce-subscriptions' ); + + $this->heading = __( 'Automatic renewal payment failed', 'woocommerce-subscriptions' ); + $this->subject = __( '[{site_title}] Automatic payment failed for {order_number}, retry scheduled to run {retry_time}', 'woocommerce-subscriptions' ); + + $this->template_html = 'emails/admin-payment-retry.php'; + $this->template_plain = 'emails/plain/admin-payment-retry.php'; + $this->template_base = plugin_dir_path( WC_Subscriptions::$plugin_file ) . 'templates/'; + + // We want all the parent's methods, with none of its properties, so call its parent's constructor, rather than my parent constructor + WC_Email::__construct(); + + // Other settings + $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) ); + } + + /** + * Trigger. + * + * @param int $order_id + */ + public function trigger( $order ) { + $this->object = $order; + $this->retry = WCS_Retry_Manager::store()->get_last_retry_for_order( $order->id );; + $this->find['order-date'] = '{order_date}'; + $this->find['order-number'] = '{order_number}'; + $this->find['retry-time'] = '{retry_time}'; + $this->replace['order-date'] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) ); + $this->replace['order-number'] = $this->object->get_order_number(); + $this->replace['retry-time'] = strtolower( wcs_get_human_time_diff( $this->retry->get_time() ) ); + + if ( ! $this->is_enabled() || ! $this->get_recipient() ) { + return; + } + + $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); + } + + /** + * Get content html. + * + * @access public + * @return string + */ + public function get_content_html() { + return wc_get_template_html( + $this->template_html, + array( + 'order' => $this->object, + 'retry' => $this->retry, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => false, + 'email' => $this, + ), + '', + $this->template_base + ); + } + + /** + * Get content plain. + * + * @return string + */ + public function get_content_plain() { + return wc_get_template_html( + $this->template_plain, + array( + 'order' => $this->object, + 'retry' => $this->retry, + 'email_heading' => $this->get_heading(), + 'sent_to_admin' => true, + 'plain_text' => true, + 'email' => $this, + ), + '', + $this->template_base + ); + } +} diff --git a/includes/gateways/class-wc-subscriptions-payment-gateways.php b/includes/gateways/class-wc-subscriptions-payment-gateways.php index 151fd36..e8346c6 100644 --- a/includes/gateways/class-wc-subscriptions-payment-gateways.php +++ b/includes/gateways/class-wc-subscriptions-payment-gateways.php @@ -21,13 +21,13 @@ class WC_Subscriptions_Payment_Gateways { */ public static function init() { - add_action( 'init', __CLASS__ . '::init_paypal', 10 ); + add_action( 'init', __CLASS__ . '::init_paypal', 5 ); // run before default priority 10 in case the site is using ALTERNATE_WP_CRON to avoid https://core.trac.wordpress.org/ticket/24160 add_filter( 'woocommerce_available_payment_gateways', __CLASS__ . '::get_available_payment_gateways' ); add_filter( 'woocommerce_no_available_payment_methods_message', __CLASS__ . '::no_available_payment_methods_message' ); - // Create a custom hook for gateways that need to manually charge recurring payments + // Trigger a hook for gateways to charge recurring payments add_action( 'woocommerce_scheduled_subscription_payment', __CLASS__ . '::gateway_scheduled_subscription_payment', 10, 1 ); // Create a gateway specific hooks for subscription events @@ -164,6 +164,21 @@ class WC_Subscriptions_Payment_Gateways { do_action( $hook_prefix . $subscription->payment_method, $subscription ); } + /** + * Fire a gateway specific hook for when a subscription renewal payment is due. + * + * @since 2.1.0 + */ + public static function trigger_gateway_renewal_payment_hook( $renewal_order ) { + if ( ! empty( $renewal_order ) && $renewal_order->get_total() > 0 && ! empty( $renewal_order->payment_method ) ) { + + // Make sure gateways are setup + WC()->payment_gateways(); + + do_action( 'woocommerce_scheduled_subscription_payment_' . $renewal_order->payment_method, $renewal_order->get_total(), $renewal_order ); + } + } + /** * Fire a gateway specific hook for when a subscription payment is due. * @@ -175,16 +190,19 @@ class WC_Subscriptions_Payment_Gateways { if ( null != $deprecated ) { _deprecated_argument( __METHOD__, '2.0', 'Second parameter is deprecated' ); $subscription = wcs_get_subscription_from_key( $deprecated ); - } else { + } elseif ( ! is_object( $subscription_id ) ) { $subscription = wcs_get_subscription( $subscription_id ); + } else { + // Support receiving a full subscription object for unit testing + $subscription = $subscription_id; } if ( false === $subscription ) { throw new InvalidArgumentException( sprintf( __( 'Subscription doesn\'t exist in scheduled action: %d', 'woocommerce-subscriptions' ), $subscription_id ) ); } - if ( ! $subscription->is_manual() && $subscription->get_total() > 0 && ! empty( $subscription->payment_method ) ) { - do_action( 'woocommerce_scheduled_subscription_payment_' . $subscription->payment_method, $subscription->get_total(), $subscription->get_last_order( 'all' ) ); + if ( ! $subscription->is_manual() ) { + self::trigger_gateway_renewal_payment_hook( $subscription->get_last_order( 'all', 'renewal' ) ); } } @@ -237,18 +255,6 @@ class WC_Subscriptions_Payment_Gateways { _deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' ); self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'expired' ); } - - /** - * Fired a gateway specific when a subscription was suspended. Suspended status was changed in 1.2 to match - * WooCommerce with the "on-hold" status. - * - * @deprecated 1.2 - * @since 1.0 - */ - public static function trigger_gateway_suspended_subscription_hook( $user_id, $subscription_key ) { - _deprecated_function( __METHOD__, '1.2', __CLASS__ . '::trigger_gateway_subscription_put_on_hold_hook( $subscription_key, $user_id )' ); - self::trigger_gateway_subscription_put_on_hold_hook( $subscription_key, $user_id ); - } } WC_Subscriptions_Payment_Gateways::init(); diff --git a/includes/gateways/paypal/class-wcs-paypal.php b/includes/gateways/paypal/class-wcs-paypal.php index 3bd34e4..cd5d215 100644 --- a/includes/gateways/paypal/class-wcs-paypal.php +++ b/includes/gateways/paypal/class-wcs-paypal.php @@ -25,6 +25,7 @@ require_once( 'includes/class-wcs-paypal-standard-change-payment-method.php' ); require_once( 'includes/admin/class-wcs-paypal-admin.php' ); require_once( 'includes/admin/class-wcs-paypal-change-payment-method-admin.php' ); require_once( 'includes/deprecated/class-wc-paypal-standard-subscriptions.php' ); +require_once( 'includes/class-wcs-paypal-standard-ipn-failure-handler.php' ); class WCS_PayPal { @@ -90,6 +91,10 @@ class WCS_PayPal { add_filter( 'woocommerce_subscriptions_admin_meta_boxes_script_parameters', __CLASS__ . '::maybe_add_change_payment_method_warning' ); + // Run the IPN failure handler attach and detach functions before and after processing to catch and log any unexpected shutdowns + add_action( 'valid-paypal-standard-ipn-request', 'WCS_PayPal_Standard_IPN_Failure_Handler::attach', -1, 1 ); + add_action( 'valid-paypal-standard-ipn-request', 'WCS_PayPal_Standard_IPN_Failure_Handler::detach', 1, 1 ); + WCS_PayPal_Supports::init(); WCS_PayPal_Status_Manager::init(); WCS_PayPal_Standard_Switcher::init(); @@ -154,7 +159,7 @@ class WCS_PayPal { update_option( 'wcs_paypal_rt_enabled_accounts', wcs_json_encode( $accounts_with_reference_transactions_enabled ) ); $reference_transactions_enabled = true; } else { - set_transient( $transient_key, $api_username, DAY_IN_SECONDS ); + set_transient( $transient_key, $api_username, WEEK_IN_SECONDS ); } } } @@ -296,20 +301,24 @@ class WCS_PayPal { */ public static function process_ipn_request( $transaction_details ) { - require_once( 'includes/class-wcs-paypal-standard-ipn-handler.php' ); - require_once( 'includes/class-wcs-paypal-reference-transaction-ipn-handler.php' ); + try { + require_once( 'includes/class-wcs-paypal-standard-ipn-handler.php' ); + require_once( 'includes/class-wcs-paypal-reference-transaction-ipn-handler.php' ); - if ( ! isset( $transaction_details['txn_type'] ) || ! in_array( $transaction_details['txn_type'], array_merge( self::get_ipn_handler( 'standard' )->get_transaction_types(), self::get_ipn_handler( 'reference' )->get_transaction_types() ) ) ) { - return; - } + if ( ! isset( $transaction_details['txn_type'] ) || ! in_array( $transaction_details['txn_type'], array_merge( self::get_ipn_handler( 'standard' )->get_transaction_types(), self::get_ipn_handler( 'reference' )->get_transaction_types() ) ) ) { + return; + } - WC_Gateway_Paypal::log( 'Subscription Transaction Type: ' . $transaction_details['txn_type'] ); - WC_Gateway_Paypal::log( 'Subscription Transaction Details: ' . print_r( $transaction_details, true ) ); + WC_Gateway_Paypal::log( 'Subscription Transaction Type: ' . $transaction_details['txn_type'] ); + WC_Gateway_Paypal::log( 'Subscription Transaction Details: ' . print_r( $transaction_details, true ) ); - if ( in_array( $transaction_details['txn_type'], self::get_ipn_handler( 'standard' )->get_transaction_types() ) ) { - self::get_ipn_handler( 'standard' )->valid_response( $transaction_details ); - } elseif ( in_array( $transaction_details['txn_type'], self::get_ipn_handler( 'reference' )->get_transaction_types() ) ) { - self::get_ipn_handler( 'reference' )->valid_response( $transaction_details ); + if ( in_array( $transaction_details['txn_type'], self::get_ipn_handler( 'standard' )->get_transaction_types() ) ) { + self::get_ipn_handler( 'standard' )->valid_response( $transaction_details ); + } elseif ( in_array( $transaction_details['txn_type'], self::get_ipn_handler( 'reference' )->get_transaction_types() ) ) { + self::get_ipn_handler( 'reference' )->valid_response( $transaction_details ); + } + } catch ( Exception $e ) { + WCS_PayPal_Standard_IPN_Failure_Handler::log_unexpected_exception( $e ); } } diff --git a/includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php b/includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php index 02aac90..fffbb12 100644 --- a/includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php +++ b/includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php @@ -107,7 +107,7 @@ class WCS_PayPal_Admin { 'type' => 'warning', // translators: placeholders are opening and closing link tags. 1$-2$: to docs on woothemes, 3$-4$ to gateway settings on the site 'text' => sprintf( esc_html__( 'PayPal is inactive for subscription transactions. Please %1$sset up the PayPal IPN%2$s and %3$senter your API credentials%4$s to enable PayPal for Subscriptions.', 'woocommerce-subscriptions' ), - '', + '', '', '', '' @@ -122,11 +122,11 @@ class WCS_PayPal_Admin { 'text' => sprintf( esc_html__( '%1$sPayPal Reference Transactions are not enabled on your account%2$s, some subscription management features are not enabled. Please contact PayPal and request they %3$senable PayPal Reference Transactions%4$s on your account. %5$sCheck PayPal Account%6$s %7$sLearn more %8$s', 'woocommerce-subscriptions' ), '', '', - '', + '', '', '

', '', - '', + '', '»' ), ); @@ -147,11 +147,11 @@ class WCS_PayPal_Admin { if ( false !== get_option( 'wcs_paypal_credentials_error' ) ) { $notices[] = array( 'type' => 'error', - // translators: placeholders are link opening and closing tags. 1$-2$: to gateway settings, 3$-4$: support docs on woothemes.com + // translators: placeholders are link opening and closing tags. 1$-2$: to gateway settings, 3$-4$: support docs on woocommerce.com 'text' => sprintf( esc_html__( 'There is a problem with PayPal. Your API credentials may be incorrect. Please update your %1$sAPI credentials%2$s. %3$sLearn more%4$s.', 'woocommerce-subscriptions' ), '', '', - '', + '', '' ), ); @@ -162,13 +162,31 @@ class WCS_PayPal_Admin { 'type' => 'error', // translators: placeholders are opening and closing link tags. 1$-2$: docs on woothemes, 3$-4$: dismiss link 'text' => sprintf( esc_html__( 'There is a problem with PayPal. Your PayPal account is issuing out-of-date subscription IDs. %1$sLearn more%2$s. %3$sDismiss%4$s.', 'woocommerce-subscriptions' ), - '', + '', '', '', '' ), ); } + + $last_ipn_error = get_option( 'wcs_fatal_error_handling_ipn', '' ); + + if ( ! empty( $last_ipn_error ) && ( false == get_option( 'wcs_fatal_error_handling_ipn_ignored', false ) || isset( $_GET['wcs_reveal_your_ipn_secrets'] ) ) ) { + $notices[] = array( + 'type' => 'error', + 'text' => sprintf( esc_html__( '%sA fatal error has occurred when processing a recent subscription payment with PayPal. Please %sopen a new ticket at WooThemes Support%s immediately to get this resolved.%sIn order to get the quickest possible response please attach a %sTemporary Admin Login%s and a copy of your PHP error logs to your support ticket.%sLast recorded error: %s', 'woocommerce-subscriptions' ), + '

', + '', + '', + '
', + '', + '', + '

', + '' . esc_html( $last_ipn_error ) . '' + ), + ); + } } if ( ! empty( $notices ) ) { @@ -185,6 +203,10 @@ class WCS_PayPal_Admin { if ( isset( $_GET['wcs_disable_paypal_invalid_profile_id_notice'] ) ) { update_option( 'wcs_paypal_invalid_profile_id', 'disabled' ); } + + if ( isset( $_GET['wcs_ipn_error_notice'] ) ) { + update_option( 'wcs_fatal_error_handling_ipn_ignored', true ); + } } /** diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php index a08baeb..e487626 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php @@ -115,9 +115,8 @@ class WCS_PayPal_Reference_Transaction_API_Response_Payment extends WCS_PayPal_R } elseif ( 'echeck' == $this->get_payment_type() ) { - // add some additional info for eCheck payments // translators: placeholder is localised datetime - $message = sprintf( __( 'expected clearing date %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), strtotime( $this->get_payment_parameter( 'EXPECTEDECHECKCLEARDATE' ) ) ) ); + $message = sprintf( __( 'expected clearing date %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), wcs_date_to_time( $this->get_payment_parameter( 'EXPECTEDECHECKCLEARDATE' ) ) ) ); } // add fraud filters diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php index 86c594c..75b24ab 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php @@ -57,6 +57,37 @@ class WCS_PayPal_Reference_Transaction_API_Response extends WC_Gateway_Paypal_Re return ( 'Success' !== $this->get_parameter( 'ACK' ) && 'SuccessWithWarning' !== $this->get_parameter( 'ACK' ) ); } + /** + * Checks if response contains an API error code or message relating to invalid credentails + * + * @link https://developer.paypal.com/docs/classic/api/errorcodes/ + * + * @return bool true if has API error relating to incorrect credentials, false otherwise + * @since 2.1 + */ + public function has_api_error_for_credentials() { + + $has_api_error_for_credentials = false; + + // assume something went wrong if ACK is missing + if ( $this->has_api_error() ) { + + foreach ( range( 0, 9 ) as $index ) { + + // Error codes refer to multiple errors, go figure, so we need to compare both error codes and error messages + $has_credentials_error_code = $this->has_parameter( "L_ERRORCODE{$index}" ) && in_array( $this->get_parameter( "L_ERRORCODE{$index}" ), array( 10002, 10008 ) ); + $has_credentials_error_message = $this->has_parameter( "L_LONGMESSAGE{$index}" ) && in_array( $this->get_parameter( "L_LONGMESSAGE{$index}" ), array( 'Username/Password is incorrect', 'Security header is not valid' ) ); + + if ( $has_credentials_error_code && $has_credentials_error_message ) { + $has_api_error_for_credentials = true; + break; + } + } + } + + return $has_api_error_for_credentials; + } + /** * Gets the API error code * diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php index b176b01..63f0f49 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php @@ -128,6 +128,11 @@ class WCS_PayPal_Reference_Transaction_API extends WCS_SV_API_Base { $reference_transactions_enabled = true; } else { $reference_transactions_enabled = false; + + // And set a flag to display invalid credentials notice + if ( $response->has_api_error_for_credentials() ) { + update_option( 'wcs_paypal_credentials_error', 'yes' ); + } } } catch ( Exception $e ) { $reference_transactions_enabled = false; diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-standard-change-payment-method.php b/includes/gateways/paypal/includes/class-wcs-paypal-standard-change-payment-method.php index d301460..3d61926 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-standard-change-payment-method.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-standard-change-payment-method.php @@ -2,9 +2,9 @@ /** * PayPal Standard Change Subscription Payment Method Class. * - * Handles the process of a customer changing the payment method on a subscription via their My Account page from or two PayPal Standard. + * Handles the process of a customer changing the payment method on a subscription via their My Account page from or to PayPal Standard. * - * @link http://docs.woothemes.com/document/subscriptions/customers-view/#section-5 + * @link http://docs.woocommerce.com/document/subscriptions/customers-view/#section-5 * * @package WooCommerce Subscriptions * @subpackage Gateways/PayPal diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-failure-handler.php b/includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-failure-handler.php new file mode 100644 index 0000000..c446e3e --- /dev/null +++ b/includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-failure-handler.php @@ -0,0 +1,140 @@ +add( 'wcs-ipn-failures', $message ); + } + + /** + * Builds an error array from exception and call @see self::log_ipn_errors() to log unhandled + * exceptions in a separate paypal log. + * + * @since 2.0.6 + * @param Exception $exception + */ + public static function log_unexpected_exception( $exception ) { + $error = array( + 'message' => $exception->getMessage(), + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'trace' => $exception->getTraceAsString(), + ); + + if ( empty( $error['message'] ) ) { + $error['message'] = 'Unhandled Exception: no message'; + } + + self::log_ipn_errors( self::$transaction_details, $error ); + } +} diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php b/includes/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php index ad62cd4..f00348a 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php @@ -39,7 +39,7 @@ class WCS_PayPal_Standard_Switcher { add_action( 'woocommerce_checkout_update_order_meta', __CLASS__ . '::save_old_paypal_meta', 15, 2 ); // Try to cancel a paypal once the switch has been successfully completed - add_action( 'woocommerce_order_status_changed', __CLASS__ . '::maybe_cancel_paypal_after_switch', 10, 3 ); + add_action( 'woocommerce_subscriptions_switch_completed', __CLASS__ . '::cancel_paypal_standard_after_switch', 10, 1 ); // Do not allow subscriptions to be switched using PayPal Standard as the payment method add_filter( 'woocommerce_available_payment_gateways', __CLASS__ . '::get_available_payment_gateways', 12, 1 ); @@ -174,22 +174,18 @@ class WCS_PayPal_Standard_Switcher { /** * Cancel subscriptions with PayPal Standard after the order has been successfully switched. * - * @param int $order_id - * @param string $old_status - * @param string $new_status - * @since 2.0.15 + * @param WC_Order $order + * @since 2.1 */ - public static function maybe_cancel_paypal_after_switch( $order_id, $old_status, $new_status ) { + public static function cancel_paypal_standard_after_switch( $order ) { - $order_completed = in_array( $new_status, array( apply_filters( 'woocommerce_payment_complete_order_status', 'processing', $order_id ), 'processing', 'completed' ) ) && in_array( $old_status, apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'on-hold', 'failed' ) ) ); + if ( 'paypal_standard' == get_post_meta( $order->id, '_old_payment_method', true ) ) { - if ( $order_completed && wcs_order_contains_switch( $order_id ) && 'paypal_standard' == get_post_meta( $order_id, '_old_payment_method', true ) ) { - - $old_profile_id = get_post_meta( $order_id, '_old_paypal_subscription_id', true ); + $old_profile_id = get_post_meta( $order->id, '_old_paypal_subscription_id', true ); if ( ! empty( $old_profile_id ) ) { - $subscriptions = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'switch' ) ); + $subscriptions = wcs_get_subscriptions_for_order( $order->id, array( 'order_type' => 'switch' ) ); foreach ( $subscriptions as $subscription ) { @@ -229,4 +225,26 @@ class WCS_PayPal_Standard_Switcher { return $available_gateways; } + + /** Deprecated Methods **/ + + /** + * Cancel subscriptions with PayPal Standard after the order has been successfully switched. + * + * @param int $order_id + * @param string $old_status + * @param string $new_status + * @since 2.0.15 + */ + public static function maybe_cancel_paypal_after_switch( $order_id, $old_status, $new_status ) { + + _deprecated_function( __METHOD__, '2.1', __CLASS__ . 'cancel_paypal_standard_after_switch( $order )' ); + + $order_completed = in_array( $new_status, array( apply_filters( 'woocommerce_payment_complete_order_status', 'processing', $order_id ), 'processing', 'completed' ) ) && in_array( $old_status, apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'on-hold', 'failed' ) ) ); + + if ( $order_completed && wcs_order_contains_switch( $order_id ) ) { + $order = wc_get_order( $order_id ); + self::cancel_paypal_standard_after_switch( $order ); + } + } } diff --git a/includes/gateways/paypal/includes/class-wcs-paypal-status-manager.php b/includes/gateways/paypal/includes/class-wcs-paypal-status-manager.php index fd6f7dd..87100aa 100644 --- a/includes/gateways/paypal/includes/class-wcs-paypal-status-manager.php +++ b/includes/gateways/paypal/includes/class-wcs-paypal-status-manager.php @@ -93,6 +93,25 @@ class WCS_PayPal_Status_Manager extends WCS_PayPal { $status_updated = true; } else { $status_updated = false; + + if ( $response->has_api_error_for_credentials() ) { + + // Store the profile ID so we can lookup which profiles are affected + $profile_ids = get_option( 'wcs_paypal_credentials_error_affected_profiles', '' ); + + if ( ! empty( $profile_ids ) ) { + $profile_ids .= ', '; + } + $profile_ids .= $profile_id; + + update_option( 'wcs_paypal_credentials_error_affected_profiles', $profile_ids ); + + // And set a flag to display notice + update_option( 'wcs_paypal_credentials_error', 'yes' ); + + // This message will be added as an order note on by WC_Subscription::update_status() + throw new Exception( sprintf( __( 'PayPal API error - credentials are incorrect.', 'woocommerce-subscriptions' ), $new_status ) ); + } } } else { $status_updated = false; diff --git a/includes/libraries/action-scheduler/action-scheduler.php b/includes/libraries/action-scheduler/action-scheduler.php index be35b6a..41b60a0 100644 --- a/includes/libraries/action-scheduler/action-scheduler.php +++ b/includes/libraries/action-scheduler/action-scheduler.php @@ -1,29 +1,29 @@ register( '1.4-dev', 'action_scheduler_initialize_1_dot_4_dev' ); + $versions->register( '1.5', 'action_scheduler_initialize_1_dot_5' ); } - function action_scheduler_initialize_1_dot_4_dev() { - require_once('classes/ActionScheduler.php'); + function action_scheduler_initialize_1_dot_5() { + require_once( 'classes/ActionScheduler.php' ); ActionScheduler::init( __FILE__ ); } diff --git a/includes/libraries/action-scheduler/classes/ActionScheduler_CronSchedule.php b/includes/libraries/action-scheduler/classes/ActionScheduler_CronSchedule.php index 6e4af2d..cfcc9eb 100644 --- a/includes/libraries/action-scheduler/classes/ActionScheduler_CronSchedule.php +++ b/includes/libraries/action-scheduler/classes/ActionScheduler_CronSchedule.php @@ -21,7 +21,7 @@ class ActionScheduler_CronSchedule implements ActionScheduler_Schedule { */ public function next( DateTime $after = NULL ) { $after = empty($after) ? clone $this->start : clone $after; - return $this->cron->getNextRunDate($after, 0, TRUE); + return $this->cron->getNextRunDate($after, 0, false); } @@ -41,4 +41,4 @@ class ActionScheduler_CronSchedule implements ActionScheduler_Schedule { $this->start = as_get_datetime_object($this->start_timestamp); } } - \ No newline at end of file + diff --git a/includes/libraries/action-scheduler/classes/ActionScheduler_wpCommentLogger.php b/includes/libraries/action-scheduler/classes/ActionScheduler_wpCommentLogger.php index aaefa2e..6f34371 100644 --- a/includes/libraries/action-scheduler/classes/ActionScheduler_wpCommentLogger.php +++ b/includes/libraries/action-scheduler/classes/ActionScheduler_wpCommentLogger.php @@ -126,11 +126,24 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger { global $wpdb; if ( 0 === $post_id ) { + $stats = $this->get_comment_count(); + } - $count = wp_cache_get( 'comments-0', 'counts' ); - if ( false !== $count ) { - return $count; - } + return $stats; + } + + /** + * Retrieve the comment counts from our cache, or the database if the cached version isn't set. + * + * @return object + */ + protected function get_comment_count() { + global $wpdb; + + $stats = get_transient( 'as_comment_count' ); + + if ( ! $stats ) { + $stats = array(); $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A ); @@ -149,6 +162,8 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger { } $stats['total_comments'] = $total; + $stats['all'] = $total; + foreach ( $approved as $key ) { if ( empty( $stats[ $key ] ) ) { $stats[ $key ] = 0; @@ -156,12 +171,22 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger { } $stats = (object) $stats; - wp_cache_set( 'comments-0', $stats, 'counts' ); + set_transient( 'as_comment_count', $stats ); } return $stats; } + /** + * Delete comment count cache whenever there is new comment or the status of a comment changes. Cache + * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called. + * + * @return void + */ + public function delete_comment_count_cache() { + delete_transient( 'as_comment_count' ); + } + /** * @codeCoverageIgnore */ @@ -177,7 +202,11 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger { add_action( 'action_scheduler_unexpected_shutdown', array( $this, 'log_unexpected_shutdown' ), 10, 2 ); add_action( 'action_scheduler_reset_action', array( $this, 'log_reset_action' ), 10, 1 ); add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 ); - add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 9, 2 ); // run before WC_Comments::wp_count_comments() + add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs + + // Delete comments count cache whenever there is a new comment or a comment status changes + add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) ); + add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) ); } public function disable_comment_counting() { diff --git a/includes/payment-retry/class-wcs-retry-admin.php b/includes/payment-retry/class-wcs-retry-admin.php new file mode 100644 index 0000000..656ebb6 --- /dev/null +++ b/includes/payment-retry/class-wcs-retry-admin.php @@ -0,0 +1,144 @@ +setting_id = $setting_id; + + add_filter( 'woocommerce_subscription_settings', array( $this, 'add_settings' ) ); + + if ( WCS_Retry_Manager::is_retry_enabled() ) { + add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 50 ); + + add_filter( 'wcs_display_date_type', array( $this, 'maybe_hide_date_type' ), 10, 3 ); + + // Display the number of retries in the Orders list table + add_action( 'manage_shop_order_posts_custom_column', __CLASS__ . '::add_column_content', 20, 2 ); + } + } + + /** + * Add a meta box to the Edit Order screen to display the retries relating to that order + * + * @return null + */ + public function add_meta_boxes() { + global $current_screen, $post_ID; + + // Only display the meta box if an order relates to a subscription + if ( 'shop_order' === get_post_type( $post_ID ) && wcs_order_contains_renewal( $post_ID ) && WCS_Retry_Manager::store()->get_retry_count_for_order( $post_ID ) > 0 ) { + add_meta_box( 'renewal_payment_retries', __( 'Automatic Failed Payment Retries', 'woocommerce-subscriptions' ), 'WCS_Meta_Box_Payment_Retries::output', 'shop_order', 'normal', 'low' ); + } + } + + /** + * Only display the retry payment date on the Edit Subscription screen if the subscription has a pending retry + * and when that is the case, do not display the next payment date (because it will still be set to the original + * payment date, in the past). + * + * @param bool $show_date_type + * @param string $date_key + * @param WC_Subscription $the_subscription + * @return bool + */ + public function maybe_hide_date_type( $show_date_type, $date_key, $the_subscription ) { + + if ( 'payment_retry' === $date_key && 0 == $the_subscription->get_time( 'payment_retry' ) ) { + $show_date_type = false; + } elseif ( 'next_payment' === $date_key && $the_subscription->get_time( 'payment_retry' ) > 0 ) { + $show_date_type = false; + } + + return $show_date_type; + } + + /** + * Dispay the number of retries on a renewal order in the Orders list table. + * + * @param string $column The string of the current column + * @param int $post_id The ID of the order + * @since 2.1 + */ + public static function add_column_content( $column, $post_id ) { + + if ( 'subscription_relationship' == $column && wcs_order_contains_renewal( $post_id ) ) { + + $retries = WCS_Retry_Manager::store()->get_retries_for_order( $post_id ); + + if ( ! empty( $retries ) ) { + + $retry_counts = array(); + $tool_tip = ''; + + foreach ( $retries as $retry ) { + $retry_counts[ $retry->get_status() ] = isset( $retry_counts[ $retry->get_status() ] ) ? ++$retry_counts[ $retry->get_status() ] : 1; + } + + foreach ( $retry_counts as $retry_status => $retry_count ) { + + switch ( $retry_status ) { + case 'pending' : + $tool_tip .= sprintf( _n( '%d Pending Payment Retry', '%d Pending Payment Retries', $retry_count, 'woocommerce-subscriptions' ), $retry_count ); + break; + case 'processing' : + $tool_tip .= sprintf( _n( '%d Processing Payment Retry', '%d Processing Payment Retries', $retry_count, 'woocommerce-subscriptions' ), $retry_count ); + break; + case 'failed' : + $tool_tip .= sprintf( _n( '%d Failed Payment Retry', '%d Failed Payment Retries', $retry_count, 'woocommerce-subscriptions' ), $retry_count ); + break; + case 'complete' : + $tool_tip .= sprintf( _n( '%d Successful Payment Retry', '%d Successful Payment Retries', $retry_count, 'woocommerce-subscriptions' ), $retry_count ); + break; + case 'cancelled' : + $tool_tip .= sprintf( _n( '%d Cancelled Payment Retry', '%d Cancelled Payment Retries', $retry_count, 'woocommerce-subscriptions' ), $retry_count ); + break; + } + + $tool_tip .= '
'; + } + + echo '
'; + } + } + } + + /** + * Add a setting to enable/disable the retry system + * + * @param array + * @return null + */ + public function add_settings( $settings ) { + + $misc_section_end = wp_list_filter( $settings, array( 'id' => 'woocommerce_subscriptions_miscellaneous', 'type' => 'sectionend' ) ); + + $spliced_array = array_splice( $settings, key( $misc_section_end ), 0, array( + array( + 'name' => __( 'Retry Failed Payments', 'woocommerce-subscriptions' ), + 'desc' => __( 'Enable automatic retry of failed recurring payments', 'woocommerce-subscriptions' ), + 'id' => $this->setting_id, + 'default' => 'no', + 'type' => 'checkbox', + 'desc_tip' => sprintf( __( 'Attempt to recover recurring revenue that would otherwise be lost due to payment methods being declined only temporarily. %sLearn more%s.', 'woocommerce-subscriptions' ), '', '' ), + ), + ) ); + + return $settings; + } +} diff --git a/includes/payment-retry/class-wcs-retry-email.php b/includes/payment-retry/class-wcs-retry-email.php new file mode 100644 index 0000000..29b975f --- /dev/null +++ b/includes/payment-retry/class-wcs-retry-email.php @@ -0,0 +1,118 @@ +has_email_template( $recipient ) ) { + $email_class = $retry_rule->get_email_template( $recipient ); + if ( class_exists( $email_class ) ) { + $email = new $email_class(); + $email->trigger( $last_order ); + } + } + } + } + + /** + * Don't send the renewal order invoice email to the customer or failed order email to the admin + * when a payment fails if there are retry rules to apply as they define which email/s to send. + * + * @since 2.1 + */ + public static function maybe_detach_email( $order_id ) { + + // We only want to detach the email if there is a retry + if ( wcs_order_contains_renewal( $order_id ) && WCS_Retry_Manager::rules()->has_rule( WCS_Retry_Manager::store()->get_retry_count_for_order( $order_id ), $order_id ) ) { + + // Remove email sent to customer email, which is sent by Subscriptions, which already removes the WooCommerce equivalent email + remove_action( 'woocommerce_order_status_failed', 'WC_Subscriptions_Email::send_renewal_order_email', 10 ); + + // Remove email sent to admin, which is sent by WooCommerce + remove_action( 'woocommerce_order_status_pending_to_failed', array( 'WC_Emails', 'send_transactional_email' ), 10, 10 ); + remove_action( 'woocommerce_order_status_on-hold_to_failed', array( 'WC_Emails', 'send_transactional_email' ), 10, 10 ); + + self::$removed_emails_for_order_id = $order_id; + } + } + + /** + * Check if we removed emails for a given order, and if we did, reattach them to the corresponding hooks + * + * @since 2.1 + */ + public static function maybe_reattach_email( $order_id, $old_status, $new_status ) { + + if ( 'failed' === $new_status && $order_id == self::$removed_emails_for_order_id ) { + + // Reattach email sent to customer email by Subscriptions, but only reattach it once + add_action( 'woocommerce_order_status_failed', 'WC_Subscriptions_Email::send_renewal_order_email' ); + + // Reattach email sent to admin, which is sent by WooCommerce + add_action( 'woocommerce_order_status_pending_to_failed', array( 'WC_Emails', 'send_transactional_email' ), 10, 10 ); + add_action( 'woocommerce_order_status_on-hold_to_failed', array( 'WC_Emails', 'send_transactional_email' ), 10, 10 ); + + self::$removed_emails_for_order_id = null; + } + } +} +WCS_Retry_Email::init(); diff --git a/includes/payment-retry/class-wcs-retry-post-store.php b/includes/payment-retry/class-wcs-retry-post-store.php new file mode 100644 index 0000000..ff1afcc --- /dev/null +++ b/includes/payment-retry/class-wcs-retry-post-store.php @@ -0,0 +1,160 @@ + __( 'Payment retry posts store details about the automatic retry of failed renewal payments.', 'woocommerce-subscriptions' ), + 'public' => false, + 'map_meta_cap' => true, + 'hierarchical' => false, + 'supports' => array( 'title', 'editor','comments' ), + 'rewrite' => false, + 'query_var' => false, + 'can_export' => true, + 'ep_mask' => EP_NONE, + 'labels' => array( + 'name' => _x( 'Renewal Payment Retries', 'Post type name', 'woocommerce-subscriptions' ), + 'singular_name' => __( 'Renewal Payment Retry', 'woocommerce-subscriptions' ), + 'menu_name' => _x( 'Renewal Payment Retries', 'Admin menu name', 'woocommerce-subscriptions' ), + 'add_new' => __( 'Add', 'woocommerce-subscriptions' ), + 'add_new_item' => __( 'Add New Retry', 'woocommerce-subscriptions' ), + 'edit' => __( 'Edit', 'woocommerce-subscriptions' ), + 'edit_item' => __( 'Edit Retry', 'woocommerce-subscriptions' ), + 'new_item' => __( 'New Retry', 'woocommerce-subscriptions' ), + 'view' => __( 'View Retry', 'woocommerce-subscriptions' ), + 'view_item' => __( 'View Retry', 'woocommerce-subscriptions' ), + 'search_items' => __( 'Search Renewal Payment Retries', 'woocommerce-subscriptions' ), + 'not_found' => __( 'No retries found', 'woocommerce-subscriptions' ), + 'not_found_in_trash' => __( 'No retries found in trash', 'woocommerce-subscriptions' ), + ), + ) + ); + } + + /** + * Save the details of a retry to the database + * + * @param WCS_Retry $retry + * @return int the retry's ID + */ + public function save( WCS_Retry $retry ) { + + $post_id = wp_insert_post( array( + 'ID' => $retry->get_id(), + 'post_type' => self::$post_type, + 'post_status' => $retry->get_status(), + 'post_parent' => $retry->get_order_id(), + 'post_date' => $retry->get_date(), + 'post_date_gmt' => $retry->get_date_gmt(), + ) ); + + // keep a record of the rule in post meta + foreach ( $retry->get_rule()->get_raw_data() as $rule_key => $rule_value ) { + update_post_meta( $post_id, '_rule_' . $rule_key, $rule_value ); + } + + return $post_id; + } + + /** + * Get the details of a retry from the database + * + * @param int $retry_id + * @return WCS_Retry + */ + public function get_retry( $retry_id ) { + + $retry_post = get_post( $retry_id ); + + if ( null !== $retry_post ) { + + $rule_data = array(); + $post_meta = get_post_meta( $retry_id ); + + foreach ( $post_meta as $meta_key => $meta_value ) { + if ( 0 === strpos( $meta_key, '_rule_' ) ) { + $rule_data[ substr( $meta_key, 6 ) ] = $meta_value[0]; + } + } + + $retry = new WCS_Retry( array( + 'id' => $retry_post->ID, + 'status' => $retry_post->post_status, + 'order_id' => $retry_post->post_parent, + 'date_gmt' => $retry_post->post_date_gmt, + 'rule_raw' => $rule_data, + ) ); + } else { + $retry = null; + } + + return $retry; + } + + /** + * + */ + public function get_retries( $args ) { + + $args = wp_parse_args( $args, array( + 'status' => 'any', + 'date_query' => array(), + ) ); + + $retry_post_ids = get_posts( array( + 'posts_per_page' => -1, + 'post_type' => self::$post_type, + 'post_status' => $args['status'], + 'date_query' => $args['date_query'], + 'fields' => 'ids', + 'orderby' => 'date', + 'order' => 'DESC', + ) ); + + $retries = array(); + + foreach ( $retry_post_ids as $retry_post_id ) { + $retries[ $retry_post_id ] = $this->get_retry( $retry_post_id ); + } + + return $retries; + } + + /** + * Get the IDs of all retries from the database for a given order + * + * @param int $order_id + * @return array + */ + public function get_retry_ids_for_order( $order_id ) { + + $retry_post_ids = get_posts( array( + 'posts_per_page' => -1, + 'post_type' => self::$post_type, + 'post_status' => 'any', + 'post_parent' => $order_id, + 'fields' => 'ids', + 'orderby' => 'ID', + 'order' => 'ASC', + ) ); + + return $retry_post_ids; + } +} diff --git a/includes/payment-retry/class-wcs-retry-rule.php b/includes/payment-retry/class-wcs-retry-rule.php new file mode 100644 index 0000000..bbcb095 --- /dev/null +++ b/includes/payment-retry/class-wcs-retry-rule.php @@ -0,0 +1,95 @@ + $rule_value ) { + $this->rule_data[ $rule_key ] = $rule_value; + } + } + + /** + * Get the time to wait between when this rule is applied (i.e. payment failed) and the retry + * should be processed. + * + * @return int + * @since 2.1 + */ + public function get_retry_interval() { + return ( isset( $this->rule_data['retry_after_interval'] ) ) ? $this->rule_data['retry_after_interval'] : 0; + } + + /** + * Check if this rule has an email template defined for sending to a specified recipient. + * + * @param string $recipient The email type based on recipient, either 'customer' or 'admin' + * @return bool + * @since 2.1 + */ + public function has_email_template( $recipient = 'customer' ) { + return ( isset( $this->rule_data[ 'email_template_' . $recipient ] ) && ! empty( $this->rule_data[ 'email_template_' . $recipient ] ) ) ? true : false; + } + + /** + * Get the email template this rule defined for sending to a specified recipient. + * + * @param string $recipient The email type based on recipient, either 'customer' or 'admin' + * @return string + * @since 2.1 + */ + public function get_email_template( $recipient = 'customer' ) { + + if ( $this->has_email_template( $recipient ) ) { + $email_template = $this->rule_data[ 'email_template_' . $recipient ]; + } else { + $email_template = ''; + } + + return $email_template; + } + + /** + * Get the status to apply to one of the related objects when this rule is applied. + * + * @param string $object The object type the status should be applied to, either 'order' or 'subscription' + * @return string + * @since 2.1 + */ + public function get_status_to_apply( $object = 'order' ) { + + if ( isset( $this->rule_data[ 'status_to_apply_to_' . $object ] ) ) { + $status = $this->rule_data[ 'status_to_apply_to_' . $object ]; + } else { + $status = ''; + } + + return $status; + } + + /** + * Get rule data as a raw array. + * + * @return array + * @since 2.1 + */ + public function get_raw_data() { + return $this->rule_data; + } +} diff --git a/includes/payment-retry/class-wcs-retry-rules.php b/includes/payment-retry/class-wcs-retry-rules.php new file mode 100644 index 0000000..5e13093 --- /dev/null +++ b/includes/payment-retry/class-wcs-retry-rules.php @@ -0,0 +1,112 @@ +retry_rule_class = apply_filters( 'wcs_retry_rule_class', 'WCS_Retry_Rule' ); + + $this->default_retry_rules = apply_filters( 'wcs_default_retry_rules', array( + array( + 'retry_after_interval' => DAY_IN_SECONDS / 2, // how long to wait before retrying + 'email_template_customer' => '', // don't bother the customer yet + 'email_template_admin' => 'WCS_Email_Payment_Retry', + 'status_to_apply_to_order' => 'pending', + 'status_to_apply_to_subscription' => 'on-hold', + ), + array( + 'retry_after_interval' => DAY_IN_SECONDS / 2, + 'email_template_customer' => 'WCS_Email_Customer_Payment_Retry', + 'email_template_admin' => 'WCS_Email_Payment_Retry', + 'status_to_apply_to_order' => 'pending', + 'status_to_apply_to_subscription' => 'on-hold', + ), + array( + 'retry_after_interval' => DAY_IN_SECONDS, + 'email_template_customer' => '', // avoid spamming the customer by not sending them an email this time either + 'email_template_admin' => 'WCS_Email_Payment_Retry', + 'status_to_apply_to_order' => 'pending', + 'status_to_apply_to_subscription' => 'on-hold', + ), + array( + 'retry_after_interval' => DAY_IN_SECONDS * 2, + 'email_template_customer' => 'WCS_Email_Customer_Payment_Retry', + 'email_template_admin' => 'WCS_Email_Payment_Retry', + 'status_to_apply_to_order' => 'pending', + 'status_to_apply_to_subscription' => 'on-hold', + ), + array( + 'retry_after_interval' => DAY_IN_SECONDS * 3, + 'email_template_customer' => 'WCS_Email_Customer_Payment_Retry', + 'email_template_admin' => 'WCS_Email_Payment_Retry', + 'status_to_apply_to_order' => 'pending', + 'status_to_apply_to_subscription' => 'on-hold', + ), + ) ); + } + + /** + * Check if a retry rule exists for a certain stage of the retry process. + * + * @param int The retry queue position to check for a rule + * @param int The ID of a WC_Order object to which the failed payment relates + * @return bool + * @since 2.1 + */ + public function has_rule( $retry_number, $order_id ) { + return ( null !== $this->get_rule( $retry_number, $order_id ) ) ? true : false; + } + + /** + * Get an instance of a retry rule for a given order and stage of the retry queue (if any). + * + * @param int The retry queue position to check for a rule + * @param int The ID of a WC_Order object to which the failed payment relates + * @return null|WCS_Retry_Rule If a retry rule exists for this stage of the retry queue and order, WCS_Retry_Rule, otherwise null. + * @since 2.1 + */ + public function get_rule( $retry_number, $order_id ) { + + $rule = null; + + if ( isset( $this->default_retry_rules[ $retry_number ] ) ) { + + $rule_array = apply_filters( 'wcs_get_retry_rule_raw', $this->default_retry_rules[ $retry_number ], $retry_number, $order_id ); + + if ( ! empty( $rule_array ) ) { + $rule = new $this->retry_rule_class( $rule_array ); + } + } + + return apply_filters( 'wcs_get_retry_rule', $rule, $retry_number, $order_id ); + } + + /** + * Get the PHP class used ti instaniate a set of raw retry rule data. + * + * @since 2.1 + */ + public function get_rule_class() { + return $this->retry_rule_class; + } +} diff --git a/includes/payment-retry/class-wcs-retry.php b/includes/payment-retry/class-wcs-retry.php new file mode 100644 index 0000000..35a5ee2 --- /dev/null +++ b/includes/payment-retry/class-wcs-retry.php @@ -0,0 +1,155 @@ +id = isset( $args['id'] ) ? $args['id'] : 0; + $this->order_id = $args['order_id']; + $this->status = isset( $args['status'] ) ? $args['status'] : 'pending'; + $this->date_gmt = isset( $args['date_gmt'] ) ? $args['date_gmt'] : gmdate( 'Y-m-d H:i:s' ); + $this->rule_raw = isset( $args['rule_raw'] ) ? $args['rule_raw'] : array(); + } + + /** + * Get the Renewal Order which this retry was run for + * + * @return int + */ + public function get_id() { + return $this->id; + } + + /** + * Get the ID of the renewal order which this retry was run for + * + * @return int + */ + public function get_order_id() { + return $this->order_id; + } + + /** + * Get the Renewal Order which this retry was run for + * + * @return string + */ + public function get_status() { + return $this->status; + } + + /** + * Update the status of a retry + * + * @since 2.1 + */ + public function update_status( $new_status ) { + + WCS_Retry_Manager::store()->save( new WCS_Retry( array( + 'id' => $this->get_id(), + 'order_id' => $this->get_order_id(), + 'date_gmt' => $this->get_date_gmt(), + 'status' => $new_status, + 'rule_raw' => $this->get_rule()->get_raw_data(), + ) ) ); + + $old_status = $this->status; + $this->status = $new_status; + + do_action( 'woocommerce_subscriptions_retry_status_updated', $this, $new_status, $old_status ); + } + + /** + * Get the date in the site's timezone when this retry was recorded + * + * @return string + */ + public function get_date() { + return get_date_from_gmt( $this->date_gmt ); + } + + /** + * Get the date in GMT/UTC timezone when this retry was recorded + * + * @return string + */ + public function get_date_gmt() { + return $this->date_gmt; + } + + /** + * Update the status of a retry and set the date to reflect that + * + * @since 2.1 + */ + public function update_date_gmt( $new_date ) { + + WCS_Retry_Manager::store()->save( new WCS_Retry( array( + 'id' => $this->get_id(), + 'order_id' => $this->get_order_id(), + 'date_gmt' => $new_date, + 'status' => $this->get_status(), + 'rule_raw' => $this->get_rule()->get_raw_data(), + ) ) ); + + $old_date = $this->date_gmt; + $this->date_gmt = $new_date; + + do_action( 'woocommerce_subscriptions_retry_date_updated', $this, $new_date, $old_date ); + } + + /** + * Get the timestamp (in GMT/UTC timezone) when this retry was recorded + * + * @return string + */ + public function get_time() { + return wcs_date_to_time( $this->get_date_gmt() ); + } + + /** + * Get an instance of the retry rule applied for this retry + * + * @return WCS_Retry_Rule + */ + public function get_rule() { + + if ( null === $this->rule ) { + $rule_class = WCS_Retry_Manager::rules()->get_rule_class(); + $this->rule = new $rule_class( $this->rule_raw ); + } + + return $this->rule; + } +} diff --git a/includes/upgrades/class-wc-subscriptions-upgrader.php b/includes/upgrades/class-wc-subscriptions-upgrader.php index 6bca8f4..648bd2b 100644 --- a/includes/upgrades/class-wc-subscriptions-upgrader.php +++ b/includes/upgrades/class-wc-subscriptions-upgrader.php @@ -85,6 +85,9 @@ class WC_Subscriptions_Upgrader { // While the upgrade is in progress, we need to block PayPal IPN messages to avoid renewals failing to process add_action( 'woocommerce_api_wc_gateway_paypal', __CLASS__ . '::maybe_block_paypal_ipn', 0 ); + + // Sometimes redirect to the Welcome/About page after an upgrade + add_action( 'woocommerce_subscriptions_upgraded', __CLASS__ . '::maybe_redirect_after_upgrade_complete', 100, 2 ); } /** @@ -167,6 +170,20 @@ class WC_Subscriptions_Upgrader { self::ajax_upgrade_handler(); } + if ( '0' != self::$active_version && version_compare( self::$active_version, '2.1.0', '<' ) ) { + + // Delete cached subscription length ranges to force an update with 2.1 + WC_Subscriptions::$cache->delete_cached( tlc_transient( 'wcs-sub-ranges-' . get_locale() )->key ); + + WCS_Upgrade_Logger::add( 'v2.1: Deleted cached subscription ranges.' ); + + include_once( 'class-wcs-upgrade-2-1.php' ); + WCS_Upgrade_2_1::set_cancelled_dates(); + + // Schedule report cache updates in the hopes that the data is ready and waiting for the store owner the first time they visit the reports pages + do_action( 'woocommerce_subscriptions_reports_schedule_cache_updates' ); + } + self::upgrade_complete(); } @@ -183,7 +200,19 @@ class WC_Subscriptions_Upgrader { delete_option( 'wc_subscriptions_is_upgrading' ); - do_action( 'woocommerce_subscriptions_upgraded', WC_Subscriptions::$version ); + do_action( 'woocommerce_subscriptions_upgraded', WC_Subscriptions::$version, self::$active_version ); + } + + /** + * Redirect to the Subscriptions major version Welcome/About page for major version updates + * + * @since 2.1 + */ + public static function maybe_redirect_after_upgrade_complete( $current_version, $previously_active_version ) { + if ( version_compare( $previously_active_version, '2.1.0', '<' ) && version_compare( $current_version, '2.1.0', '>=' ) ) { + wp_safe_redirect( self::$about_page_url ); + exit(); + } } /** @@ -296,7 +325,7 @@ class WC_Subscriptions_Upgrader { $results = array( 'upgraded_count' => 0, // translators: 1$: error message, 2$: opening link tag, 3$: closing link tag - 'message' => sprintf( __( 'Unable to upgrade subscriptions.
Error: %1$s
Please refresh the page and try again. If problem persists, %2$scontact support%3$s.', 'woocommerce-subscriptions' ), '' . $e->getMessage(). '', '', '' ), + 'message' => sprintf( __( 'Unable to upgrade subscriptions.
Error: %1$s
Please refresh the page and try again. If problem persists, %2$scontact support%3$s.', 'woocommerce-subscriptions' ), '' . $e->getMessage(). '', '', '' ), 'status' => 'error', ); } @@ -347,7 +376,7 @@ class WC_Subscriptions_Upgrader { 'repaired_count' => 0, 'unrepaired_count' => 0, // translators: 1$: error message, 2$: opening link tag, 3$: closing link tag - 'message' => sprintf( _x( 'Unable to repair subscriptions.
Error: %1$s
Please refresh the page and try again. If problem persists, %2$scontact support%3$s.', 'Error message that gets sent to front end when upgrading Subscriptions', 'woocommerce-subscriptions' ), '' . $e->getMessage(). '', '', '' ), + 'message' => sprintf( _x( 'Unable to repair subscriptions.
Error: %1$s
Please refresh the page and try again. If problem persists, %2$scontact support%3$s.', 'Error message that gets sent to front end when upgrading Subscriptions', 'woocommerce-subscriptions' ), '' . $e->getMessage(). '', '', '' ), 'status' => 'error', ); } @@ -551,7 +580,7 @@ class WC_Subscriptions_Upgrader { * @since 1.4 */ public static function updated_welcome_page() { - $about_page = add_dashboard_page( __( 'Welcome to WooCommerce Subscriptions 2.0', 'woocommerce-subscriptions' ), __( 'About WooCommerce Subscriptions', 'woocommerce-subscriptions' ), 'manage_options', 'wcs-about', __CLASS__ . '::about_screen' ); + $about_page = add_dashboard_page( __( 'Welcome to WooCommerce Subscriptions 2.1', 'woocommerce-subscriptions' ), __( 'About WooCommerce Subscriptions', 'woocommerce-subscriptions' ), 'manage_options', 'wcs-about', __CLASS__ . '::about_screen' ); add_action( 'admin_print_styles-'. $about_page, __CLASS__ . '::admin_css' ); add_action( 'admin_head', __CLASS__ . '::admin_head' ); } @@ -580,7 +609,10 @@ class WC_Subscriptions_Upgrader { * Output the about screen. */ public static function about_screen() { + $active_version = self::$active_version; + $settings_page = admin_url( 'admin.php?page=wc-settings&tab=subscriptions' ); + include_once( 'templates/wcs-about.php' ); } diff --git a/includes/upgrades/class-wcs-repair-2-0-2.php b/includes/upgrades/class-wcs-repair-2-0-2.php index 6b66cf2..de34cfc 100644 --- a/includes/upgrades/class-wcs-repair-2-0-2.php +++ b/includes/upgrades/class-wcs-repair-2-0-2.php @@ -269,7 +269,7 @@ class WCS_Repair_2_0_2 { // if we have a date, make sure it's valid if ( null !== $old_next_payment_date ) { - if ( strtotime( $old_next_payment_date ) <= gmdate( 'U' ) ) { + if ( wcs_date_to_time( $old_next_payment_date ) <= gmdate( 'U' ) ) { $repair_date = $subscription->calculate_date( 'next_payment' ); if ( 0 == $repair_date ) { $repair_date = false; @@ -283,7 +283,7 @@ class WCS_Repair_2_0_2 { // let's just double check we shouldn't have a date set by recalculating it $calculated_next_payment_date = $subscription->calculate_date( 'next_payment' ); - if ( 0 != $calculated_next_payment_date && strtotime( $calculated_next_payment_date ) > gmdate( 'U' ) ) { + if ( 0 != $calculated_next_payment_date && wcs_date_to_time( $calculated_next_payment_date ) > gmdate( 'U' ) ) { $repair_date = $calculated_next_payment_date; } else { $repair_date = false; diff --git a/includes/upgrades/class-wcs-repair-2-0.php b/includes/upgrades/class-wcs-repair-2-0.php index d792baf..4d6b4f6 100644 --- a/includes/upgrades/class-wcs-repair-2-0.php +++ b/includes/upgrades/class-wcs-repair-2-0.php @@ -263,11 +263,11 @@ class WCS_Repair_2_0 { // let's get the last 2 renewal orders $last_renewal_order = array_shift( $renewal_orders ); $last_renewal_date = $last_renewal_order->order_date; - $last_renewal_timestamp = strtotime( $last_renewal_date ); + $last_renewal_timestamp = wcs_date_to_time( $last_renewal_date ); $second_renewal_order = array_shift( $renewal_orders ); $second_renewal_date = $second_renewal_order->order_date; - $second_renewal_timestamp = strtotime( $second_renewal_date ); + $second_renewal_timestamp = wcs_date_to_time( $second_renewal_date ); $interval = 1; @@ -336,11 +336,11 @@ class WCS_Repair_2_0 { // let's get the last 2 renewal orders $last_renewal_order = array_shift( $renewal_orders ); $last_renewal_date = $last_renewal_order->order_date; - $last_renewal_timestamp = strtotime( $last_renewal_date ); + $last_renewal_timestamp = wcs_date_to_time( $last_renewal_date ); $second_renewal_order = array_shift( $renewal_orders ); $second_renewal_date = $second_renewal_order->order_date; - $second_renewal_timestamp = strtotime( $second_renewal_date ); + $second_renewal_timestamp = wcs_date_to_time( $second_renewal_date ); $subscription['interval'] = wcs_estimate_periods_between( $second_renewal_timestamp, $last_renewal_timestamp, $subscription['period'] ); @@ -369,7 +369,7 @@ class WCS_Repair_2_0 { // If we can calculate it from the effective date and expiry date if ( 'expired' == $subscription['status'] && array_key_exists( 'expiry_date', $subscription ) && ! empty( $subscription['expiry_date'] ) && null !== $effective_start_date && array_key_exists( 'period', $subscription ) && ! empty( $subscription['period'] ) && array_key_exists( 'interval', $subscription ) && ! empty( $subscription['interval'] ) ) { - $intervals = wcs_estimate_periods_between( strtotime( $effective_start_date ), strtotime( $subscription['expiry_date'] ), $subscription['period'], 'floor' ); + $intervals = wcs_estimate_periods_between( wcs_date_to_time( $effective_start_date ), wcs_date_to_time( $subscription['expiry_date'] ), $subscription['period'], 'floor' ); $subscription['length'] = $intervals; } else { $subscription['length'] = 0; @@ -470,7 +470,7 @@ class WCS_Repair_2_0 { } else { - $subscription['end_date'] = wcs_add_time( 5, 'hours', strtotime( $last_order->order_date ) ); + $subscription['end_date'] = wcs_add_time( 5, 'hours', wcs_date_to_time( $last_order->order_date ) ); } } else { @@ -547,8 +547,8 @@ class WCS_Repair_2_0 { * @return integer number of seconds between the two */ private static function time_diff( $to, $from ) { - $to = strtotime( $to ); - $from = strtotime( $from ); + $to = wcs_date_to_time( $to ); + $from = wcs_date_to_time( $from ); return abs( $to - $from ); } @@ -602,7 +602,7 @@ class WCS_Repair_2_0 { $formatted_date = 0; WCS_Upgrade_Logger::add( sprintf( '-- For order %d: Repairing date type "%s": fetch of date unsuccessfull: no action present. Date is 0.', $subscription['order_id'], $type ) ); } else { - $formatted_date = date( 'Y-m-d H:i:s', $next_date_timestamp ); + $formatted_date = gmdate( 'Y-m-d H:i:s', $next_date_timestamp ); WCS_Upgrade_Logger::add( sprintf( '-- For order %d: Repairing date type "%s": fetch of date successfull. New date is %s', $subscription['order_id'], $type, $formatted_date ) ); } @@ -624,7 +624,7 @@ class WCS_Repair_2_0 { } elseif ( array_key_exists( 'trial_period', $subscription ) && ! empty( $subscription['trial_period'] ) && array_key_exists( 'trial_length', $subscription ) && ! empty( $subscription['trial_length'] ) && array_key_exists( 'start_date', $subscription ) && ! empty( $subscription['start_date'] ) ) { // calculate the end of trial from interval, period and start date - $effective_date = date( 'Y-m-d H:i:s', strtotime( '+' . $subscription['trial_length'] . ' ' . $subscription['trial_period'], strtotime( $subscription['start_date'] ) ) ); + $effective_date = gmdate( 'Y-m-d H:i:s', wcs_add_time( $subscription['trial_length'], $subscription['trial_period'], wcs_date_to_time( $subscription['start_date'] ) ) ); } elseif ( array_key_exists( 'start_date', $subscription ) && ! empty( $subscription['start_date'] ) ) { diff --git a/includes/upgrades/class-wcs-upgrade-2-0.php b/includes/upgrades/class-wcs-upgrade-2-0.php index 25a6ae4..32bb2dc 100644 --- a/includes/upgrades/class-wcs-upgrade-2-0.php +++ b/includes/upgrades/class-wcs-upgrade-2-0.php @@ -508,7 +508,7 @@ class WCS_Upgrade_2_0 { if ( 'end_of_prepaid_term' == $new_key ) { wc_schedule_single_action( $next_scheduled, 'woocommerce_scheduled_subscription_end_of_prepaid_term', array( 'subscription_id' => $new_subscription->id ) ); } else { - $dates_to_update[ $new_key ] = date( 'Y-m-d H:i:s', $next_scheduled ); + $dates_to_update[ $new_key ] = gmdate( 'Y-m-d H:i:s', $next_scheduled ); } } } diff --git a/includes/upgrades/class-wcs-upgrade-2-1.php b/includes/upgrades/class-wcs-upgrade-2-1.php new file mode 100644 index 0000000..2b6fcdb --- /dev/null +++ b/includes/upgrades/class-wcs-upgrade-2-1.php @@ -0,0 +1,54 @@ +query( 'SET SQL_BIG_SELECTS = 1;' ); + + $cancelled_date_meta_key = wcs_get_date_meta_key( 'cancelled' ); + + // Run two separate insert queries for pending cancellation and cancelled subscriptions. This could easily be done in one query, but we'll run it in two separate queries to minimise issues with large databases. + foreach ( array( 'wc-pending-cancel', 'wc-cancelled' ) as $post_status ) { + + $rows_inserted = $wpdb->query( $wpdb->prepare( + "INSERT INTO {$wpdb->postmeta}(post_id, meta_key, meta_value) + SELECT ID, %s, post_modified_gmt + FROM {$wpdb->posts} as posts + WHERE post_status = %s + AND NOT EXISTS ( + SELECT null + FROM {$wpdb->postmeta} as postmeta + WHERE postmeta.post_id = posts.ID + AND postmeta.meta_key = %s + ) + ", + $cancelled_date_meta_key, + $post_status, + $cancelled_date_meta_key + ) ); + + WCS_Upgrade_Logger::add( sprintf( 'v2.1: Set _schedule_cancelled date to post_modified_gmt column value for %d subscriptions with %s status.', $rows_inserted, $post_status ) ); + } + } +} diff --git a/includes/upgrades/class-wcs-upgrade-logger.php b/includes/upgrades/class-wcs-upgrade-logger.php index e762324..1ef1de5 100644 --- a/includes/upgrades/class-wcs-upgrade-logger.php +++ b/includes/upgrades/class-wcs-upgrade-logger.php @@ -57,7 +57,7 @@ class WCS_Upgrade_Logger { */ public static function schedule_cleanup() { $time_to_cleanup = gmdate( 'U' ) + self::$weeks_until_cleanup * WEEK_IN_SECONDS; - self::add( sprintf( 'Upgrade complete. Scheduling log cleanup for %s GMT/UTC', date( 'Y-m-d H:i:s', $time_to_cleanup ) ) ); + self::add( sprintf( 'Upgrade complete. Scheduling log cleanup for %s GMT/UTC', gmdate( 'Y-m-d H:i:s', $time_to_cleanup ) ) ); wc_schedule_single_action( $time_to_cleanup, 'woocommerce_subscriptions_clear_upgrade_log' ); } } diff --git a/includes/upgrades/templates/wcs-about-2-0.php b/includes/upgrades/templates/wcs-about-2-0.php new file mode 100644 index 0000000..f59daff --- /dev/null +++ b/includes/upgrades/templates/wcs-about-2-0.php @@ -0,0 +1,196 @@ + + +
+ +

+ +
+ + + +
+ +
+ +
+ +

+ + + + +

+ +
+

+
+ +
+
+ +
+ +
+

+

+

+

', '' ); ?> +

+
+
+ +
+ +
+ +
+ +
+

+

+

tags + printf( esc_html__( 'The new interface is also built on the existing %sEdit Order%s screen. If you\'ve ever modified an order, you already know how to modify a subscription.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

', '', '', '' ); ?> +

+
+
+ +
+
+ +
+ +
+

+

+ tags + printf( esc_html__( 'Your customers can now view the full details of a subscription, including line items, billing and shipping address, billing schedule and renewal orders, from a special %sMy Account > View Subscription%s page.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

+

+ ', '' ); ?> +

+
+
+
+
+ +
+ +
+ +

+

) tags + printf( esc_html__( 'By default, adding new files to an existing subscription product will automatically provide active subscribers with access to the new files. However, now you can enable a %snew content dripping setting%s to provide subscribers with access to new files only after the next renewal payment.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

) tags + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> +

+
+ +
+ +

+

tags + printf( esc_html__( 'For a store manager to change a subscription from automatic to manual renewal payments (or manual to automatic) with Subscriptions v1.5, the database needed to be modified directly. Subscriptions now provides a way for payment gateways to allow you to change that from the new %sEdit Subscription%s interface.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

) tags + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> +

+
+ +
+ +

+

tags + printf( esc_html__( 'It was already possible to change a subscription\'s next payment date, but some store managers wanted to provide a customer with an extended free trial or add an extra month to the expiration date. Now you can change all of these dates from the %sEdit Subscription%s screen.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

) tags + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> +

+
+ +
+
+ +
+
+

+

', '' ); ?>

+
+
+ +
+ +

+

+ +
+
+

', '' ); ?> +

+

+

tags + printf( esc_html__( 'Developers can also now use all the familiar WordPress functions, like %sget_posts()%s, to query or modify subscription data.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+
+
+

tags + printf( esc_html__( 'New %sWC_Subscription%s Object', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

+

tags, no need to order them + printf( esc_html__( 'Because the %sWC_Subscription%s class extends %sWC_Order%s, you can use its familiar methods, like %s$subscription->update_status()%s or %s$subscription->get_total()%s.', 'woocommerce-subscriptions' ), '', '', '', '', '', '', '', '' ); ?> +

+
+
+

+

+

tags, no need to order them + printf( esc_html__( 'Want to list all the subscriptions on a site? Get %sexample.com/wc-api/v2/subscriptions/%s. Want the details of a specific subscription? Get %s/wc-api/v2/subscriptions//%s.', 'woocommerce-subscriptions' ), '', '', '', '' ); ?> +

+
+
+
+
+ +
+
diff --git a/includes/upgrades/templates/wcs-about.php b/includes/upgrades/templates/wcs-about.php index 172547e..45da673 100644 --- a/includes/upgrades/templates/wcs-about.php +++ b/includes/upgrades/templates/wcs-about.php @@ -1,27 +1,26 @@
-

+

- + ', '' ); ?>
@@ -33,27 +32,27 @@ $settings_page = admin_url( 'admin.php?page=wc-settings&tab=subscriptions' );

- - + +

-
- +
-

-

-

-

', '' ); ?> +

+

+

+

+

+ +

@@ -61,136 +60,156 @@ $settings_page = admin_url( 'admin.php?page=wc-settings&tab=subscriptions' );
- +
-

-

-

tags - printf( esc_html__( 'The new interface is also built on the existing %sEdit Order%s screen. If you\'ve ever modified an order, you already know how to modify a subscription.', 'woocommerce-subscriptions' ), '', '' ); ?> -

-

', '', '', '' ); ?> +

+

+

+
    +
  • +
  • +
  • +
  • +
+

+

+ +

- +
-

-

- tags - printf( esc_html__( 'Your customers can now view the full details of a subscription, including line items, billing and shipping address, billing schedule and renewal orders, from a special %sMy Account > View Subscription%s page.', 'woocommerce-subscriptions' ), '', '' ); ?> -

-

-

- ', '' ); ?> +

+

+
    +
  • +
  • +
  • +
+

Settings > Emails%s administration screen.', 'woocommerce-subscriptions' ), '', '' ); ?>

+

+ +

-
+ +
+ +

+

- -

+ +

+

+

) tags - printf( esc_html__( 'By default, adding new files to an existing subscription product will automatically provide active subscribers with access to the new files. However, now you can enable a %snew content dripping setting%s to provide subscribers with access to new files only after the next renewal payment.', 'woocommerce-subscriptions' ), '', '' ); ?> -

-

) tags - printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?>

- -

-

tags - printf( esc_html__( 'For a store manager to change a subscription from automatic to manual renewal payments (or manual to automatic) with Subscriptions v1.5, the database needed to be modified directly. Subscriptions now provides a way for payment gateways to allow you to change that from the new %sEdit Subscription%s interface.', 'woocommerce-subscriptions' ), '', '' ); ?> -

+ +

+

+

) tags - printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?>

- -

-

tags - printf( esc_html__( 'It was already possible to change a subscription\'s next payment date, but some store managers wanted to provide a customer with an extended free trial or add an extra month to the expiration date. Now you can change all of these dates from the %sEdit Subscription%s screen.', 'woocommerce-subscriptions' ), '', '' ); ?> -

+ +

+

+

) tags - printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?> + printf( esc_html__( '%sLearn more »%s', 'woocommerce-subscriptions' ), '', '' ); ?>

-
-
-

-

', '' ); ?>

-
-
-

-

', '' ); ?> -

-

-

tags - printf( esc_html__( 'Developers can also now use all the familiar WordPress functions, like %sget_posts()%s, to query or modify subscription data.', 'woocommerce-subscriptions' ), '', '' ); ?> + printf( esc_html__( 'Customise Retry Rules', 'woocommerce-subscriptions' ), '', '' ); ?> + +

+

tags, no need to order them + printf( esc_html__( 'With the %s\'wcs_default_retry_rules\'%s filter, you can define a set of default rules to apply to all failed payments in your store.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

tags, no need to order them + printf( esc_html__( 'To apply a specific rule based on certain conditions, like high value orders or an infrequent renewal schedule, you can use the retry specific %s\'wcs_get_retry_rule\'%s filter. This provides the ID of the renewal order for the failed payment, which can be used to find information about the products, subscription and totals to which the failed payment relates.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

', '' ); ?>

-

tags - printf( esc_html__( 'New %sWC_Subscription%s Object', 'woocommerce-subscriptions' ), '', '' ); ?> -

-

+

+

tag linking to WC API docs, $2: closing tag, $3: opening tag linking to WP API docs, $4: closing tag + printf( esc_html__( 'WooCommerce 2.6 added support for %1$sREST API%2$s endpoints built on WordPress core\'s %3$sREST API%4$s infrastructure.', 'woocommerce-subscriptions' ), '', '', '', '' ); ?> +

+

+

tags, no need to order them - printf( esc_html__( 'Because the %sWC_Subscription%s class extends %sWC_Order%s, you can use its familiar methods, like %s$subscription->update_status()%s or %s$subscription->get_total()%s.', 'woocommerce-subscriptions' ), '', '', '', '', '', '', '', '' ); ?> + printf( esc_html__( 'Want to list all the subscriptions on a site? Get %s/wp-json/wc/v1/subscriptions%s.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

tags, no need to order them + printf( esc_html__( 'Want the details of a specific subscription? Get %s/wp-json/wc/v1/subscriptions//%s.', 'woocommerce-subscriptions' ), '', '' ); ?> +

+

', '' ); ?>

-

-

+

', '' ); ?> +

+

tags, no need to order them - printf( esc_html__( 'Want to list all the subscriptions on a site? Get %sexample.com/wc-api/v2/subscriptions/%s. Want the details of a specific subscription? Get %s/wc-api/v2/subscriptions//%s.', 'woocommerce-subscriptions' ), '', '', '', '' ); ?> + // translators: placeholders are opening and closing tags + printf( esc_html__( 'Subscriptions 2.1 now passes the renewal order\'s total, making it possible to add a fee or discount to the renewal order with simple one-liners like %s$order->add_fee()%s or %s$order->add_coupon()%s.', 'woocommerce-subscriptions' ), '', '', '', '' ); ?> +

+

tags + printf( esc_html__( 'Subscriptions also now uses the renewal order to setup the cart for %smanual renewals%s, making it easier to add products or discounts to a single renewal paid manually.', 'woocommerce-subscriptions' ), '', '' ); ?>

-
+
- +

+

diff --git a/includes/wcs-cart-functions.php b/includes/wcs-cart-functions.php index 5f4880a..d530857 100644 --- a/includes/wcs-cart-functions.php +++ b/includes/wcs-cart-functions.php @@ -65,6 +65,8 @@ function wcs_cart_totals_shipping_html() { $chosen_initial_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : ''; $chosen_recurring_method = isset( WC()->session->chosen_shipping_methods[ $recurring_cart_key . '_' . $i ] ) ? WC()->session->chosen_shipping_methods[ $recurring_cart_key . '_' . $i ] : $chosen_initial_method; + $shipping_selection_displayed = false; + if ( ( 1 === count( $package['rates'] ) ) || ( isset( $package['rates'][ $chosen_initial_method ] ) && isset( $initial_packages[ $i ] ) && $package['rates'] == $initial_packages[ $i ]['rates'] && apply_filters( 'wcs_cart_totals_shipping_html_price_only', true, $package, $recurring_cart ) ) ) { $shipping_method = ( 1 === count( $package['rates'] ) ) ? current( $package['rates'] ) : $package['rates'][ $chosen_initial_method ]; // packages match, display shipping amounts only @@ -87,6 +89,8 @@ function wcs_cart_totals_shipping_html() { // Display the options $product_names = array(); + $shipping_selection_displayed = true; + if ( $show_package_name ) { $package_name = apply_filters( 'woocommerce_shipping_package_name', sprintf( _n( 'Shipping', 'Shipping %d', ( $i + 1 ), 'woocommerce-subscriptions' ), ( $i + 1 ) ), $i, $package ); } else { @@ -109,7 +113,7 @@ function wcs_cart_totals_shipping_html() { ); $show_package_name = false; } - do_action( 'woocommerce_subscriptions_after_recurring_shipping_rates', $index, $base_package, $recurring_cart, $chosen_recurring_method ); + do_action( 'woocommerce_subscriptions_after_recurring_shipping_rates', $index, $base_package, $recurring_cart, $chosen_recurring_method, $shipping_selection_displayed ); } } } @@ -318,7 +322,7 @@ function wcs_cart_pluck( $cart, $field, $default = 0 ) { function wcs_add_cart_first_renewal_payment_date( $order_total_html, $cart ) { if ( 0 !== $cart->next_payment_date ) { - $first_renewal_date = date_i18n( wc_date_format(), strtotime( get_date_from_gmt( $cart->next_payment_date ) ) ); + $first_renewal_date = date_i18n( wc_date_format(), wcs_date_to_time( get_date_from_gmt( $cart->next_payment_date ) ) ); // translators: placeholder is a date $order_total_html .= '
' . sprintf( __( 'First renewal: %s', 'woocommerce-subscriptions' ), $first_renewal_date ) . '
'; } diff --git a/includes/wcs-compatibility-functions.php b/includes/wcs-compatibility-functions.php new file mode 100644 index 0000000..fad0da1 --- /dev/null +++ b/includes/wcs-compatibility-functions.php @@ -0,0 +1,45 @@ +', $tip, esc_url( WC()->plugin_url() ) ); + } + + return $help_tip; +} diff --git a/includes/wcs-formatting-functions.php b/includes/wcs-formatting-functions.php index 0b82514..324500f 100644 --- a/includes/wcs-formatting-functions.php +++ b/includes/wcs-formatting-functions.php @@ -211,3 +211,28 @@ function wcs_price_string( $subscription_details ) { return apply_filters( 'woocommerce_subscription_price_string', $subscription_string, $subscription_details ); } + +/** + * Display a human friendly time diff for a given timestamp, e.g. "In 12 hours" or "12 hours ago". + * + * @param int $timestamp_gmt + * @return string A human friendly string to display for the timestamp's date + * @since 2.1 + */ +function wcs_get_human_time_diff( $timestamp_gmt ) { + + $time_diff = $timestamp_gmt - current_time( 'timestamp', true ); + + if ( $time_diff > 0 && $time_diff < WEEK_IN_SECONDS ) { + // translators: placeholder is human time diff (e.g. "3 weeks") + $date_to_display = sprintf( __( 'In %s', 'woocommerce-subscriptions' ), human_time_diff( current_time( 'timestamp', true ), $timestamp_gmt ) ); + } elseif ( $time_diff < 0 && absint( $time_diff ) < WEEK_IN_SECONDS ) { + // translators: placeholder is human time diff (e.g. "3 weeks") + $date_to_display = sprintf( __( '%s ago', 'woocommerce-subscriptions' ), human_time_diff( current_time( 'timestamp', true ), $timestamp_gmt ) ); + } else { + $timestamp_site = wcs_date_to_time( get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $timestamp_gmt ) ) ); + $date_to_display = date_i18n( wc_date_format(), $timestamp_site ) . ' ' . date_i18n( wc_time_format(), $timestamp_site ); + } + + return $date_to_display; +} diff --git a/includes/wcs-helper-functions.php b/includes/wcs-helper-functions.php index 8d4d347..2331b27 100644 --- a/includes/wcs-helper-functions.php +++ b/includes/wcs-helper-functions.php @@ -116,7 +116,7 @@ function wcs_json_encode( $data ) { * @param $new_value An value to insert * @return The new array if the $needle key exists, otherwise an unmodified $haystack */ -function wcs_array_insert_after( $needle, $haystack, $new_key, $new_value) { +function wcs_array_insert_after( $needle, $haystack, $new_key, $new_value ) { if ( array_key_exists( $needle, $haystack ) ) { diff --git a/includes/wcs-limit-functions.php b/includes/wcs-limit-functions.php new file mode 100644 index 0000000..5e3956b --- /dev/null +++ b/includes/wcs-limit-functions.php @@ -0,0 +1,47 @@ +product_custom_fields['_subscription_limit'][0] ) ) { + return 'no'; + } elseif ( 'yes' == $product->product_custom_fields['_subscription_limit'][0] ) { // backward compatibility + return 'any'; + } else { + return $product->product_custom_fields['_subscription_limit'][0]; + } +} + +/** + * Returns true if product is limited to one active subscription and user currently has this product on-hold. + * + * @param int|WC_Product $product A WC_Product object or the ID of a product + * @return boolean + */ +function wcs_is_product_limited_for_user( $product, $user_id = 0 ) { + if ( ! is_object( $product ) ) { + $product = wc_get_product( $product ); + } + + return ( ( 'active' == wcs_get_product_limitation( $product ) && wcs_user_has_subscription( $user_id, $product->id, 'on-hold' ) ) || ( 'no' !== wcs_get_product_limitation( $product ) && wcs_user_has_subscription( $user_id, $product->id, wcs_get_product_limitation( $product ) ) ) ) ? true : false; +} diff --git a/includes/wcs-order-functions.php b/includes/wcs-order-functions.php index c3e1e8f..c5b4461 100644 --- a/includes/wcs-order-functions.php +++ b/includes/wcs-order-functions.php @@ -236,12 +236,43 @@ function wcs_create_order_from_subscription( $subscription, $type ) { wc_add_order_item_meta( $recurring_item_id, $meta_key, maybe_unserialize( $meta_value ) ); } } + + // If the line item we're adding is a product line item and that product still exists, trigger the 'woocommerce_order_add_product' hook + if ( 'line_item' == $item['type'] && isset( $item['product_id'] ) ) { + + $product_id = wcs_get_canonical_product_id( $item ); + $product = wc_get_product( $product_id ); + + if ( false !== $product ) { + + $args = array( + 'totals' => array( + 'subtotal' => $item['line_subtotal'], + 'total' => $item['line_total'], + 'subtotal_tax' => $item['line_subtotal_tax'], + 'tax' => $item['line_tax'], + 'tax_data' => maybe_unserialize( $item['line_tax_data'] ), + ), + ); + + // If we have a variation, get the attribute meta data from teh item to pass to callbacks + if ( ! empty( $item['variation_id'] ) && ! empty( $product->variation_data ) ) { + foreach ( $product->variation_data as $attribute => $variation ) { + if ( isset( $item[ str_replace( 'attribute_', '', $attribute ) ] ) ) { + $args['variation'][ $attribute ] = $item[ str_replace( 'attribute_', '', $attribute ) ]; + } + } + } + + do_action( 'woocommerce_order_add_product', $new_order->id, $recurring_item_id, $product, $item['qty'], $args ); + } + } } // If we got here, the subscription was created without problems $wpdb->query( 'COMMIT' ); - return apply_filters( 'wcs_new_order_created', $new_order, $subscription ); + return apply_filters( 'wcs_new_order_created', $new_order, $subscription, $type ); } catch ( Exception $e ) { // There was an error adding the subscription @@ -378,6 +409,91 @@ function wcs_order_contains_subscription( $order, $order_type = array( 'parent', return $contains_subscription; } +/** + * Get all the orders that relate to a subscription in some form (rather than only the orders associated with + * a specific subscription). + * + * @param string $return_fields The columns to return, either 'all' or 'ids' + * @param array|string $order_type Can include 'any', 'parent', 'renewal', 'resubscribe' and/or 'switch'. Defaults to 'parent'. + * @return array The orders that relate to a subscription, if any. Will contain either as just IDs or WC_Order objects depending on $return_fields value. + * @since 2.1 + */ +function wcs_get_subscription_orders( $return_fields = 'ids', $order_type = 'parent' ) { + global $wpdb; + + // Accept either an array or string (to make it more convenient for singular types, like 'parent' or 'any') + if ( ! is_array( $order_type ) ) { + $order_type = array( $order_type ); + } + + $any_order_type = in_array( 'any', $order_type ) ? true : false; + $return_fields = ( 'ids' == $return_fields ) ? $return_fields : 'all'; + + $orders = array(); + $order_ids = array(); + + if ( $any_order_type || in_array( 'parent', $order_type ) ) { + $order_ids = array_merge( $order_ids, $wpdb->get_col( + "SELECT DISTINCT post_parent FROM {$wpdb->posts} + WHERE post_type = 'shop_subscription' + AND post_parent <> 0" + ) ); + } + + if ( $any_order_type || in_array( 'renewal', $order_type ) || in_array( 'resubscribe', $order_type ) || in_array( 'switch', $order_type ) ) { + + $meta_query = array( + 'relation' => 'OR', + ); + + if ( $any_order_type || in_array( 'renewal', $order_type ) ) { + $meta_query[] = array( + 'key' => '_subscription_renewal', + 'compare' => 'EXISTS', + ); + } + + if ( $any_order_type || in_array( 'switch', $order_type ) ) { + $meta_query[] = array( + 'key' => '_subscription_switch', + 'compare' => 'EXISTS', + ); + } + + // $any_order_type handled by 'parent' query above as all resubscribe orders are all parent orders + if ( in_array( 'resubscribe', $order_type ) && ! in_array( 'parent', $order_type ) ) { + $meta_query[] = array( + 'key' => '_subscription_resubscribe', + 'compare' => 'EXISTS', + ); + } + + if ( count( $meta_query ) > 1 ) { + $order_ids = array_merge( $order_ids, get_posts( array( + 'posts_per_page' => -1, + 'post_type' => 'shop_order', + 'post_status' => 'any', + 'fields' => 'ids', + 'orderby' => 'ID', + 'order' => 'DESC', + 'meta_query' => $meta_query, + ) ) ); + } + } + + if ( 'all' == $return_fields ) { + foreach ( $order_ids as $order_id ) { + $orders[ $order_id ] = wc_get_order( $order_id ); + } + } else { + foreach ( $order_ids as $order_id ) { + $orders[ $order_id ] = $order_id; + } + } + + return apply_filters( 'wcs_get_subscription_orders', $orders, $return_fields, $order_type ); +} + /** * A wrapper for getting a specific item from a subscription. * diff --git a/includes/wcs-renewal-functions.php b/includes/wcs-renewal-functions.php index 3ed3236..bd33ab4 100644 --- a/includes/wcs-renewal-functions.php +++ b/includes/wcs-renewal-functions.php @@ -115,12 +115,16 @@ function wcs_get_subscriptions_for_renewal_order( $order ) { $order = wc_get_order( $order ); } - $subscriptions = array(); - $subscription_ids = get_post_meta( $order->id, '_subscription_renewal', false ); + $subscriptions = array(); - foreach ( $subscription_ids as $subscription_id ) { - if ( wcs_is_subscription( $subscription_id ) ) { - $subscriptions[ $subscription_id ] = wcs_get_subscription( $subscription_id ); + // Only use the order if we actually found a valid order object + if ( is_object( $order ) ) { + $subscription_ids = get_post_meta( $order->id, '_subscription_renewal', false ); + + foreach ( $subscription_ids as $subscription_id ) { + if ( wcs_is_subscription( $subscription_id ) ) { + $subscriptions[ $subscription_id ] = wcs_get_subscription( $subscription_id ); + } } } diff --git a/includes/wcs-resubscribe-functions.php b/includes/wcs-resubscribe-functions.php index f4e00d7..d8d5ad4 100644 --- a/includes/wcs-resubscribe-functions.php +++ b/includes/wcs-resubscribe-functions.php @@ -191,7 +191,7 @@ function wcs_can_user_resubscribe_to( $subscription, $user_id = '' ) { $can_user_resubscribe = false; - } elseif ( ! $subscription->has_status( array( 'cancelled', 'expired', 'trash' ) ) ) { + } elseif ( ! $subscription->has_status( array( 'pending-cancel', 'cancelled', 'expired', 'trash' ) ) ) { $can_user_resubscribe = false; @@ -229,7 +229,7 @@ function wcs_can_user_resubscribe_to( $subscription, $user_id = '' ) { break; } - if ( 'active' == $product->limit_subscriptions && ( wcs_user_has_subscription( $user_id, $product->id, 'on-hold' ) || wcs_user_has_subscription( $user_id, $product->id, 'active' ) ) ) { + if ( 'active' == wcs_get_product_limitation( $product ) && ( wcs_user_has_subscription( $user_id, $product->id, 'on-hold' ) || wcs_user_has_subscription( $user_id, $product->id, 'active' ) ) ) { $has_active_limited_subscription = true; break; } diff --git a/includes/wcs-time-functions.php b/includes/wcs-time-functions.php index 2a8fb6e..4c42891 100644 --- a/includes/wcs-time-functions.php +++ b/includes/wcs-time-functions.php @@ -78,7 +78,7 @@ function wcs_get_subscription_ranges_tlc() { foreach ( array( 'day', 'week', 'month', 'year' ) as $period ) { $subscription_lengths = array( - _x( 'all time', 'Subscription length (eg "$10 per month for _all time_")', 'woocommerce-subscriptions' ), + _x( 'Never expire', 'Subscription length', 'woocommerce-subscriptions' ), ); switch ( $period ) { @@ -214,10 +214,14 @@ function wcs_get_subscription_trial_lengths( $subscription_period = '' ) { */ function wcs_add_time( $number_of_periods, $period, $from_timestamp ) { - if ( 'month' == $period ) { - $next_timestamp = wcs_add_months( $from_timestamp, $number_of_periods ); + if ( $number_of_periods > 0 ) { + if ( 'month' == $period ) { + $next_timestamp = wcs_add_months( $from_timestamp, $number_of_periods ); + } else { + $next_timestamp = wcs_strtotime_dark_knight( "+ {$number_of_periods} {$period}", $from_timestamp ); + } } else { - $next_timestamp = strtotime( "+ {$number_of_periods} {$period}", $from_timestamp ); + $next_timestamp = $from_timestamp; } return $next_timestamp; @@ -239,17 +243,17 @@ function wcs_add_time( $number_of_periods, $period, $from_timestamp ) { */ function wcs_add_months( $from_timestamp, $months_to_add ) { - $first_day_of_month = date( 'Y-m', $from_timestamp ) . '-1'; - $days_in_next_month = date( 't', strtotime( "+ {$months_to_add} month", strtotime( $first_day_of_month ) ) ); + $first_day_of_month = gmdate( 'Y-m', $from_timestamp ) . '-1'; + $days_in_next_month = gmdate( 't', wcs_strtotime_dark_knight( "+ {$months_to_add} month", wcs_date_to_time( $first_day_of_month ) ) ); // Payment is on the last day of the month OR number of days in next billing month is less than the the day of this month (i.e. current billing date is 30th January, next billing date can't be 30th February) - if ( date( 'd m Y', $from_timestamp ) === date( 't m Y', $from_timestamp ) || date( 'd', $from_timestamp ) > $days_in_next_month ) { + if ( gmdate( 'd m Y', $from_timestamp ) === gmdate( 't m Y', $from_timestamp ) || gmdate( 'd', $from_timestamp ) > $days_in_next_month ) { for ( $i = 1; $i <= $months_to_add; $i++ ) { - $next_month = strtotime( '+ 3 days', $from_timestamp ); // Add 3 days to make sure we get to the next month, even when it's the 29th day of a month with 31 days - $next_timestamp = $from_timestamp = strtotime( date( 'Y-m-t H:i:s', $next_month ) ); // NB the "t" to get last day of next month + $next_month = wcs_add_time( 3, 'days', $from_timestamp ); // Add 3 days to make sure we get to the next month, even when it's the 29th day of a month with 31 days + $next_timestamp = $from_timestamp = wcs_date_to_time( gmdate( 'Y-m-t H:i:s', $next_month ) ); // NB the "t" to get last day of next month } } else { // Safe to just add a month - $next_timestamp = strtotime( "+ {$months_to_add} month", $from_timestamp ); + $next_timestamp = wcs_strtotime_dark_knight( "+ {$months_to_add} month", $from_timestamp ); } return $next_timestamp; @@ -389,13 +393,13 @@ function wcs_estimate_period_between( $last_date, $second_date, $interval = 1 ) $interval = 1; } - $last_timestamp = strtotime( $last_date ); - $second_timestamp = strtotime( $second_date ); + $last_timestamp = wcs_date_to_time( $last_date ); + $second_timestamp = wcs_date_to_time( $second_date ); $earlier_timestamp = min( $last_timestamp, $second_timestamp ); $later_timestamp = max( $last_timestamp, $second_timestamp ); - $days_in_month = date( 't', $earlier_timestamp ); + $days_in_month = gmdate( 't', $earlier_timestamp ); $difference = absint( $last_timestamp - $second_timestamp ); $period_in_seconds = round( $difference / $interval ); $possible_periods = array(); @@ -609,13 +613,69 @@ function wcs_is_datetime_mysql_format( $time ) { $match = preg_match( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $time ); // parses time, returns false for invalid dates - $valid_time = strtotime( $time ); + $valid_time = wcs_date_to_time( $time ); } // magic number -2209078800 is strtotime( '1900-01-00 00:00:00' ). Needed to achieve parity with strptime return ( $match && false !== $valid_time && -2209078800 <= $valid_time ) ? true : false; } +/** + * Convert a date string into a timestamp without ever adding or deducting time. + * + * strtotime() would be handy for this purpose, but alas, if other code running on the server + * is calling date_default_timezone_set() to change the timezone, strtotime() will assume the + * date is in that timezone unless the timezone is specific on the string (which it isn't for + * any MySQL formatted date) and attempt to convert it to UTC time by adding or deducting the + * GMT/UTC offset for that timezone, so for example, when 3rd party code has set the servers + * timezone using date_default_timezone_set( 'America/Los_Angeles' ) doing something like + * gmdate( "Y-m-d H:i:s", strtotime( gmdate( "Y-m-d H:i:s" ) ) ) will actually add 7 hours to + * the date even though it is a date in UTC timezone because the timezone wasn't specificed. + * + * This makes sure the date is never converted. + * + * @param string $date_string A date string formatted in MySQl or similar format that will map correctly when instantiating an instance of DateTime() + * @return int Unix timestamp representation of the timestamp passed in without any changes for timezones + */ +function wcs_date_to_time( $date_string ) { + + if ( 0 == $date_string ) { + return 0; + } + + $date_obj = new DateTime( $date_string, new DateTimeZone( 'UTC' ) ); + + return $date_obj->format( 'U' ); +} + +/** + * A wrapper for strtotime() designed to stand up against those who want to watch the WordPress burn. + * + * One day WordPress will require Harvey Dent (aka PHP 5.3) then we can use DateTime::add() instead, + * but for now, this ensures when using strtotime() to add time to a timestamp, there are no additional + * changes for server specific timezone additions or deductions. + * + * @param string $time_string A string representation of a date in any format that can be parsed by strtotime() + * @return int Unix timestamp representation of the timestamp passed in without any changes for timezones + */ +function wcs_strtotime_dark_knight( $time_string, $from_timestamp = null ) { + + $original_timezone = date_default_timezone_get(); + + // this should be UTC anyway as WordPress sets it to that, but some plugins and l33t h4xors just want to watch the world burn and set it to something else + date_default_timezone_set( 'UTC' ); + + if ( null === $from_timestamp ) { + $next_timestamp = strtotime( $time_string ); + } else { + $next_timestamp = strtotime( $time_string, $from_timestamp ); + } + + date_default_timezone_set( $original_timezone ); + + return $next_timestamp; +} + /** * Find the average number of days for a given billing period and interval. * @@ -642,3 +702,59 @@ function wcs_get_days_in_cycle( $period, $interval ) { return apply_filters( 'wcs_get_days_in_cycle', $days_in_cycle, $period, $interval ); } + +/** + * Get an instance of the site's timezone. + * + * @return DateTimeZone Timezone object for the timezone the site is using. + */ +function wcs_get_sites_timezone() { + + if ( class_exists( 'ActionScheduler_TimezoneHelper' ) ) { + + // Use Action Scheduler's version when possible as it caches the data + $local_timezone = ActionScheduler_TimezoneHelper::get_local_timezone(); + + } else { + + $tzstring = get_option( 'timezone_string' ); + + if ( empty( $tzstring ) ) { + + $gmt_offset = get_option( 'gmt_offset' ); + + if ( 0 == $gmt_offset ) { + + $tzstring = 'UTC'; + + } else { + + $gmt_offset *= HOUR_IN_SECONDS; + $tzstring = timezone_name_from_abbr( '', $gmt_offset ); + + if ( false === $tzstring ) { + + $is_dst = date( 'I' ); + + foreach ( timezone_abbreviations_list() as $abbr ) { + + foreach ( $abbr as $city ) { + if ( $city['dst'] == $is_dst && $city['offset'] == $gmt_offset ) { + $tzstring = $city['timezone_id']; + break 2; + } + } + } + } + + if ( false === $tzstring ) { + $tzstring = 'UTC'; + } + } + } + + $local_timezone = new DateTimeZone( $tzstring ); + } + + return $local_timezone; +} diff --git a/includes/wcs-user-functions.php b/includes/wcs-user-functions.php index c915661..5576906 100644 --- a/includes/wcs-user-functions.php +++ b/includes/wcs-user-functions.php @@ -235,7 +235,7 @@ function wcs_can_user_put_subscription_on_hold( $subscription, $user = '' ) { if ( $user->ID == $subscription->get_user_id() ) { // Make sure subscription suspension count hasn't been reached - $suspension_count = $subscription->suspension_count; + $suspension_count = intval( $subscription->suspension_count ); $allowed_suspensions = get_option( WC_Subscriptions_Admin::$option_prefix . '_max_customer_suspensions', 0 ); if ( 'unlimited' === $allowed_suspensions || $allowed_suspensions > $suspension_count ) { // 0 not > anything so prevents a customer ever being able to suspend @@ -345,8 +345,21 @@ function wcs_user_has_capability( $allcaps, $caps, $args ) { $allcaps['subscribe_again'] = true; } break; + case 'pay_for_order' : + $user_id = $args[1]; + $order = wc_get_order( $args[2] ); + + if ( $order && wcs_order_contains_subscription( $order, 'any' ) ) { + + if ( $user_id === $order->get_user_id() ) { + $allcaps['pay_for_order'] = true; + } else { + unset( $allcaps['pay_for_order'] ); + } + } + break; } } return $allcaps; } -add_filter( 'user_has_cap', 'wcs_user_has_capability', 10, 3 ); +add_filter( 'user_has_cap', 'wcs_user_has_capability', 15, 3 ); diff --git a/languages/woocommerce-subscriptions.pot b/languages/woocommerce-subscriptions.pot index ecafd58..74be202 100644 --- a/languages/woocommerce-subscriptions.pot +++ b/languages/woocommerce-subscriptions.pot @@ -2,10 +2,10 @@ # This file is distributed under the same license as the WooCommerce Subscriptions package. msgid "" msgstr "" -"Project-Id-Version: WooCommerce Subscriptions 2.0.20\n" +"Project-Id-Version: WooCommerce Subscriptions 2.1.0\n" "Report-Msgid-Bugs-To: " "https://github.com/Prospress/woocommerce-subscriptions/issues\n" -"POT-Creation-Date: 2016-09-23 23:32:44+00:00\n" +"POT-Creation-Date: 2016-11-12 07:04:14+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -15,69 +15,74 @@ msgstr "" "X-Generator: grunt-wp-i18n 0.5.4\n" "Language: en_US\n" +#: includes/admin/class-wc-subscriptions-admin.php:124 +msgid "Simple subscription" +msgstr "" + #: includes/admin/class-wc-subscriptions-admin.php:125 -msgid "Simple Subscription" +msgid "Variable subscription" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:126 -#: woocommerce-subscriptions.php:601 -msgid "Variable Subscription" +#: includes/admin/class-wc-subscriptions-admin.php:143 +msgid "Choose the subscription price, billing interval and period." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:151 -#: templates/admin/deprecated/html-variation-price.php:20 -#: templates/admin/deprecated/html-variation-price.php:30 -#: templates/admin/html-variation-price.php:45 +#: includes/admin/class-wc-subscriptions-admin.php:156 +#: templates/admin/html-variation-price.php:44 #. translators: placeholder is a currency symbol / code -msgid "Subscription Price (%s)" +msgid "Subscription price (%s)" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:164 -#: templates/admin/deprecated/html-variation-price.php:46 -msgid "Subscription Periods" +#: includes/admin/class-wc-subscriptions-admin.php:159 +msgid "Subscription interval" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:173 -#: includes/admin/meta-boxes/views/html-subscription-schedule.php:32 -#: templates/admin/deprecated/html-variation-price.php:57 -msgid "Billing Period" +#: includes/admin/class-wc-subscriptions-admin.php:165 +#: includes/admin/class-wc-subscriptions-admin.php:298 +msgid "Subscription period" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:184 -#: includes/admin/class-wc-subscriptions-admin.php:325 -#: templates/admin/deprecated/html-variation-price.php:69 -msgid "Subscription Length" +#: includes/admin/class-wc-subscriptions-admin.php:179 +#: includes/admin/class-wc-subscriptions-admin.php:299 +#: templates/admin/html-variation-price.php:66 +msgid "Subscription length" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:194 -#: templates/admin/deprecated/html-variation-price.php:85 +#: includes/admin/class-wc-subscriptions-admin.php:182 +msgid "" +"Automatically expire the subscription after this length of time. This " +"length is in addition to any free trial or amount of time provided before a " +"synchronised first renewal date." +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:191 +#: templates/admin/html-variation-price.php:20 #. translators: %s is a currency symbol / code -msgid "Sign-up Fee (%s)" +msgid "Sign-up fee (%s)" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:196 +#: includes/admin/class-wc-subscriptions-admin.php:193 msgid "" "Optionally include an amount to be charged at the outset of the " "subscription. The sign-up fee will be charged immediately, even if the " "product has a free trial or the payment dates are synced." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:209 -#: templates/admin/deprecated/html-variation-price.php:97 -#: templates/admin/deprecated/html-variation-price.php:104 -msgid "Free Trial" +#: includes/admin/class-wc-subscriptions-admin.php:204 +#: templates/admin/html-variation-price.php:25 +msgid "Free trial" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:216 +#: includes/admin/class-wc-subscriptions-admin.php:207 #: templates/admin/deprecated/html-variation-price.php:115 msgid "Subscription Trial Period" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:246 -msgid "One Time Shipping" +#: includes/admin/class-wc-subscriptions-admin.php:239 +msgid "One time shipping" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:247 +#: includes/admin/class-wc-subscriptions-admin.php:240 msgid "" "Shipping for subscription products is normally charged on the initial order " "and all renewal orders. Enable this to only charge shipping once on the " @@ -85,80 +90,53 @@ msgid "" "not have a free trial or a synced renewal date." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:269 -msgid "Limit Subscription" +#: includes/admin/class-wc-subscriptions-admin.php:295 +msgid "Subscription pricing" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:271 -#. translators: placeholders are opening and closing link tags -msgid "" -"Only allow a customer to have one subscription to this product. %sLearn " -"more%s." +#: includes/admin/class-wc-subscriptions-admin.php:296 +msgid "Subscription sign-up fee" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:273 -msgid "Do not limit" +#: includes/admin/class-wc-subscriptions-admin.php:297 +msgid "Subscription billing interval" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:274 -msgid "Limit to one active subscription" +#: includes/admin/class-wc-subscriptions-admin.php:300 +msgid "Free trial length" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:275 -msgid "Limit to one of any status" +#: includes/admin/class-wc-subscriptions-admin.php:301 +msgid "Free trial period" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:321 -msgid "Subscription Pricing" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:322 -msgid "Subscription Sign-up Fee" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:323 -msgid "Subscription Billing Interval" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:324 -msgid "Subscription Period" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:326 -msgid "Free Trial Length" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:327 -msgid "Free Trial Period" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:650 +#: includes/admin/class-wc-subscriptions-admin.php:624 msgid "" "Unable to change subscription status to \"%s\". Please assign a customer to " "the subscription to activate it." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:692 +#: includes/admin/class-wc-subscriptions-admin.php:666 msgid "" "Trashing this order will also trash the subscriptions purchased with the " "order." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:705 +#: includes/admin/class-wc-subscriptions-admin.php:679 msgid "Enter the new period, either day, week, month or year:" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:706 +#: includes/admin/class-wc-subscriptions-admin.php:680 msgid "Enter a new length (e.g. 5):" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:707 +#: includes/admin/class-wc-subscriptions-admin.php:681 msgid "" "Enter a new interval as a single number (e.g. to charge every 2nd month, " "enter 2):" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:712 +#: includes/admin/class-wc-subscriptions-admin.php:686 msgid "" "You are about to trash one or more orders which contain a subscription.\n" "\n" @@ -166,7 +144,7 @@ msgid "" "orders." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:725 +#: includes/admin/class-wc-subscriptions-admin.php:699 msgid "" "WARNING: Bad things are about to happen!\n" "\n" @@ -178,13 +156,13 @@ msgid "" "gateway." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:726 +#: includes/admin/class-wc-subscriptions-admin.php:700 msgid "" "You are deleting a subscription item. You will also need to manually cancel " "and trash the subscription on the Manage Subscriptions screen." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:733 +#: includes/admin/class-wc-subscriptions-admin.php:707 msgid "" "Warning: Deleting a user will also delete the user's subscriptions. The " "user's orders will remain but be reassigned to the 'Guest' user.\n" @@ -193,78 +171,59 @@ msgid "" "subscriptions?" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:796 -msgid "Active Subscriber?" +#: includes/admin/class-wc-subscriptions-admin.php:770 +msgid "Active subscriber?" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:839 +#: includes/admin/class-wc-subscriptions-admin.php:813 msgid "Manage Subscriptions" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:843 -#: woocommerce-subscriptions.php:209 +#: includes/admin/class-wc-subscriptions-admin.php:817 +#: woocommerce-subscriptions.php:214 msgid "Search Subscriptions" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:863 -#: includes/admin/class-wc-subscriptions-admin.php:959 -#: includes/class-wcs-query.php:90 includes/class-wcs-query.php:110 -#: includes/class-wcs-query.php:112 woocommerce-subscriptions.php:200 -#: woocommerce-subscriptions.php:213 +#: includes/admin/class-wc-subscriptions-admin.php:837 +#: includes/admin/class-wc-subscriptions-admin.php:933 +#: includes/admin/class-wcs-admin-reports.php:55 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:654 +#: includes/class-wcs-query.php:93 includes/class-wcs-query.php:113 +#: includes/class-wcs-query.php:115 woocommerce-subscriptions.php:205 +#: woocommerce-subscriptions.php:218 msgid "Subscriptions" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1006 -#. translators: $1-2: opening and closing tags of a link that takes to PayPal -#. settings, $3-4: opening and closing tags of a link that takes to Woo -#. marketplace / Stripe product page -msgid "" -"No payment gateways capable of processing automatic subscription payments " -"are enabled. Please enable the %1$sPayPal Standard%2$s gateway or get the " -"%3$sfree Stripe extension%4$s if you want to process automatic payments." -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1009 -#. translators: placeholder is name of a gateway -msgid "The %s gateway can process automatic subscription payments." -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1012 -#. translators: %1$s - a comma separated list of gateway names (e.g. "stripe, -#. paypal, worldpay"), %2$s - one name of gateway (e.g. "authorize.net") -msgid "The %1$s & %2$s gateways can process automatic subscription payments." -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1018 +#: includes/admin/class-wc-subscriptions-admin.php:973 msgid "Button Text" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1025 +#: includes/admin/class-wc-subscriptions-admin.php:980 msgid "Add to Cart Button Text" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1026 +#: includes/admin/class-wc-subscriptions-admin.php:981 msgid "" "A product displays a button with the text \"Add to Cart\". By default, a " "subscription changes this to \"Sign Up Now\". You can customise the button " "text for subscriptions here." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1030 -#: includes/admin/class-wc-subscriptions-admin.php:1041 +#: includes/admin/class-wc-subscriptions-admin.php:985 +#: includes/admin/class-wc-subscriptions-admin.php:996 #: includes/class-wc-product-subscription-variation.php:75 -#: includes/class-wc-product-subscription.php:115 -#: includes/class-wc-product-variable-subscription.php:101 -#: includes/class-wc-subscriptions-product.php:130 -#: woocommerce-subscriptions.php:456 woocommerce-subscriptions.php:1110 +#: includes/class-wc-product-subscription.php:122 +#: includes/class-wc-product-variable-subscription.php:108 +#: includes/class-wc-subscriptions-product.php:127 +#: woocommerce-subscriptions.php:461 msgid "Sign Up Now" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1036 +#: includes/admin/class-wc-subscriptions-admin.php:991 msgid "Place Order Button Text" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1037 +#: includes/admin/class-wc-subscriptions-admin.php:992 msgid "" "Use this field to customise the text displayed on the checkout button when " "an order contains a subscription. Normally the checkout submission button " @@ -272,11 +231,11 @@ msgid "" "changed to \"Sign Up Now\"." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1049 +#: includes/admin/class-wc-subscriptions-admin.php:1004 msgid "Roles" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1052 +#: includes/admin/class-wc-subscriptions-admin.php:1007 #. translators: placeholders are tags msgid "" "Choose the default roles to assign to active and inactive subscribers. For " @@ -285,46 +244,46 @@ msgid "" "allocated these roles to prevent locking out administrators." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1057 +#: includes/admin/class-wc-subscriptions-admin.php:1012 msgid "Subscriber Default Role" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1058 +#: includes/admin/class-wc-subscriptions-admin.php:1013 msgid "" "When a subscription is activated, either manually or after a successful " "purchase, new users will be assigned this role." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1069 +#: includes/admin/class-wc-subscriptions-admin.php:1024 msgid "Inactive Subscriber Role" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1070 +#: includes/admin/class-wc-subscriptions-admin.php:1025 msgid "" "If a subscriber's subscription is manually cancelled or expires, she will " "be assigned this role." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1090 +#: includes/admin/class-wc-subscriptions-admin.php:1045 msgid "Manual Renewal Payments" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1091 +#: includes/admin/class-wc-subscriptions-admin.php:1046 msgid "Accept Manual Renewals" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1096 +#: includes/admin/class-wc-subscriptions-admin.php:1051 #. translators: placeholders are opening and closing link tags msgid "" "With manual renewals, a customer's subscription is put on-hold until they " "login and pay to renew it. %sLearn more%s." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1102 +#: includes/admin/class-wc-subscriptions-admin.php:1057 msgid "Turn off Automatic Payments" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1107 +#: includes/admin/class-wc-subscriptions-admin.php:1062 #. translators: placeholders are opening and closing link tags msgid "" "If you never want a customer to be automatically charged for a subscription " @@ -332,11 +291,11 @@ msgid "" "more%s." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1122 +#: includes/admin/class-wc-subscriptions-admin.php:1077 msgid "Customer Suspensions" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1129 +#: includes/admin/class-wc-subscriptions-admin.php:1084 msgid "" "Set a maximum number of times a customer can suspend their account for each " "billing period. For example, for a value of 3 and a subscription billed " @@ -346,28 +305,28 @@ msgid "" "Set this to 0 to turn off the customer suspension feature completely." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1133 +#: includes/admin/class-wc-subscriptions-admin.php:1088 msgid "Mixed Checkout" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1134 +#: includes/admin/class-wc-subscriptions-admin.php:1089 msgid "Allow subscriptions and products to be purchased simultaneously." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1138 +#: includes/admin/class-wc-subscriptions-admin.php:1093 msgid "Allow subscriptions and products to be purchased in a single transaction." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1142 -#: includes/upgrades/templates/wcs-about.php:108 +#: includes/admin/class-wc-subscriptions-admin.php:1097 +#: includes/upgrades/templates/wcs-about-2-0.php:108 msgid "Drip Downloadable Content" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1143 +#: includes/admin/class-wc-subscriptions-admin.php:1098 msgid "Enable dripping for downloadable content on subscription products." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1147 +#: includes/admin/class-wc-subscriptions-admin.php:1102 msgid "" "Enabling this grants access to new downloadable files added to a product " "only after the next renewal is processed.%sBy default, access to new " @@ -375,18 +334,87 @@ msgid "" "customer that has an active subscription with that product." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1153 -msgid "Payment Gateways" +#: includes/admin/class-wc-subscriptions-admin.php:1138 +#. translators: $1-$2: opening and closing tags, $3-$4: opening and +#. closing tags +msgid "" +"%1$sWooCommerce Subscriptions Installed%2$s – %3$sYou're ready to " +"start selling subscriptions!%4$s" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1161 +#: includes/admin/class-wc-subscriptions-admin.php:1143 +msgid "Add a Subscription Product" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1144 +#: includes/upgrades/templates/wcs-about-2-0.php:35 +#: includes/upgrades/templates/wcs-about.php:34 +#: woocommerce-subscriptions.php:944 +msgid "Settings" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1230 +#. translators: placeholder is a number +msgid "We can't find a subscription with ID #%d. Perhaps it was deleted?" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1263 +#: includes/admin/class-wc-subscriptions-admin.php:1268 +#. translators: placeholders are opening link tag, ID of sub, and closing link +#. tag +msgid "Showing orders for %sSubscription %s%s" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1292 +#. translators: number of 1$: days, 2$: weeks, 3$: months, 4$: years +msgid "The trial period can not exceed: %1s, %2s, %3s or %4s." +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1297 +#. translators: placeholder is a time period (e.g. "4 weeks") +msgid "The trial period can not exceed %s." +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1353 +#: includes/admin/class-wc-subscriptions-admin.php:1406 +msgid "Yes" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1353 +msgid "No" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1389 +msgid "Automatic Recurring Payments" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1406 +msgid "" +"Supports automatic renewal payments with the WooCommerce Subscriptions " +"extension." +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1458 +#. translators: $1-2: opening and closing tags of a link that takes to Woo +#. marketplace / Stripe product page +msgid "" +"No payment gateways capable of processing automatic subscription payments " +"are enabled. If you would like to process automatic payments, we recommend " +"the %1$sfree Stripe extension%2$s." +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1463 +msgid "Recurring Payments" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:1471 #. translators: placeholders are opening and closing link tags msgid "" -"Other payment gateways can be used to process %smanual subscription renewal " -"payments%s only." +"Payment gateways which don't support automatic recurring payments can be " +"used to process %smanual subscription renewal payments%s." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1168 +#: includes/admin/class-wc-subscriptions-admin.php:1478 #. translators: $1-$2: opening and closing tags. Link to documents->payment #. gateways, 3$-4$: opening and closing tags. Link to woothemes extensions shop #. page @@ -395,97 +423,38 @@ msgid "" "the official %3$sWooCommerce Marketplace%4$s." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1205 -#. translators: $1-$2: opening and closing tags, $3-$4: opening and -#. closing tags -msgid "" -"%1$sWooCommerce Subscriptions Installed%2$s – %3$sYou're ready to " -"start selling subscriptions!%4$s" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1210 -msgid "Add a Subscription Product" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1211 -#: includes/upgrades/templates/wcs-about.php:35 -#: woocommerce-subscriptions.php:960 -msgid "Settings" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1297 -#. translators: placeholder is a number -msgid "We can't find a subscription with ID #%d. Perhaps it was deleted?" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1330 -#: includes/admin/class-wc-subscriptions-admin.php:1335 -#. translators: placeholders are opening link tag, ID of sub, and closing link -#. tag -msgid "Showing orders for %sSubscription %s%s" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1359 -#. translators: number of 1$: days, 2$: weeks, 3$: months, 4$: years -msgid "The trial period can not exceed: %1s, %2s, %3s or %4s." -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1364 -#. translators: placeholder is a time period (e.g. "4 weeks") -msgid "The trial period can not exceed %s." -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1420 -#: includes/admin/class-wc-subscriptions-admin.php:1473 -msgid "Yes" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1420 -msgid "No" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1456 -msgid "Automatic Recurring Payments" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:1473 -msgid "" -"Supports automatic renewal payments with the WooCommerce Subscriptions " -"extension." -msgstr "" - -#: includes/admin/class-wcs-admin-meta-boxes.php:60 -#: includes/admin/class-wcs-admin-meta-boxes.php:64 +#: includes/admin/class-wcs-admin-meta-boxes.php:62 +#: includes/admin/class-wcs-admin-meta-boxes.php:66 #: templates/myaccount/related-orders.php:15 msgid "Related Orders" msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:103 +#: includes/admin/class-wcs-admin-meta-boxes.php:105 msgid "Please enter a start date in the past." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:104 +#: includes/admin/class-wcs-admin-meta-boxes.php:106 msgid "Please enter a date at least one hour into the future." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:105 +#: includes/admin/class-wcs-admin-meta-boxes.php:107 msgid "Please enter a date after the trial end." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:106 -#: includes/admin/class-wcs-admin-meta-boxes.php:107 +#: includes/admin/class-wcs-admin-meta-boxes.php:108 +#: includes/admin/class-wcs-admin-meta-boxes.php:109 msgid "Please enter a date after the start date." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:108 +#: includes/admin/class-wcs-admin-meta-boxes.php:110 msgid "Please enter a date before the next payment." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:109 +#: includes/admin/class-wcs-admin-meta-boxes.php:111 msgid "Please enter a date after the next payment." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:110 +#: includes/admin/class-wcs-admin-meta-boxes.php:112 msgid "" "Are you sure you want to process a renewal?\n" "\n" @@ -493,34 +462,46 @@ msgid "" "are enabled)." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:130 +#: includes/admin/class-wcs-admin-meta-boxes.php:121 +msgid "" +"Are you sure you want to retry payment for this renewal order?\n" +"\n" +"This will attempt to charge the customer and send renewal order emails (if " +"emails are enabled)." +msgstr "" + +#: includes/admin/class-wcs-admin-meta-boxes.php:140 msgid "Process renewal" msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:133 +#: includes/admin/class-wcs-admin-meta-boxes.php:143 msgid "Create pending renewal order" msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:147 +#: includes/admin/class-wcs-admin-meta-boxes.php:146 +msgid "Retry Renewal Payment" +msgstr "" + +#: includes/admin/class-wcs-admin-meta-boxes.php:160 msgid "Process renewal order action requested by admin." msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:166 +#: includes/admin/class-wcs-admin-meta-boxes.php:179 msgid "Create pending renewal order requested by admin action." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:114 +#: includes/admin/class-wcs-admin-post-types.php:193 msgid "Search for a product…" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:287 +#: includes/admin/class-wcs-admin-post-types.php:366 #. translators: placeholder is the number of subscriptions updated msgid "%s subscription status changed." msgid_plural "%s subscription statuses changed." msgstr[0] "" msgstr[1] "" -#: includes/admin/class-wcs-admin-post-types.php:294 +#: includes/admin/class-wcs-admin-post-types.php:373 #. translators: 1$: is the number of subscriptions not updated, 2$: is the #. error message msgid "%1$s subscription could not be updated: %2$s" @@ -528,7 +509,7 @@ msgid_plural "%1$s subscriptions could not be updated: %2$s" msgstr[0] "" msgstr[1] "" -#: includes/admin/class-wcs-admin-post-types.php:316 +#: includes/admin/class-wcs-admin-post-types.php:397 #: includes/admin/meta-boxes/views/html-related-orders-table.php:20 #: templates/myaccount/my-subscriptions.php:26 #: templates/myaccount/my-subscriptions.php:40 @@ -540,168 +521,193 @@ msgstr[1] "" msgid "Status" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:317 +#: includes/admin/class-wcs-admin-post-types.php:398 #: includes/admin/meta-boxes/class-wcs-meta-box-related-orders.php:61 #: templates/emails/cancelled-subscription.php:26 +#: templates/emails/expired-subscription.php:26 +#: templates/emails/on-hold-subscription.php:26 #: templates/emails/subscription-info.php:18 #: templates/myaccount/my-subscriptions.php:25 #: templates/myaccount/related-subscriptions.php:20 -#: woocommerce-subscriptions.php:201 +#: woocommerce-subscriptions.php:206 msgid "Subscription" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:318 +#: includes/admin/class-wcs-admin-post-types.php:399 msgid "Items" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:319 +#: includes/admin/class-wcs-admin-post-types.php:400 msgid "Total" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:320 +#: includes/admin/class-wcs-admin-post-types.php:401 msgid "Start Date" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:321 +#: includes/admin/class-wcs-admin-post-types.php:402 msgid "Trial End" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:322 +#: includes/admin/class-wcs-admin-post-types.php:403 msgid "Next Payment" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:323 +#: includes/admin/class-wcs-admin-post-types.php:404 msgid "Last Payment" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:324 +#: includes/admin/class-wcs-admin-post-types.php:405 msgid "End Date" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:365 +#: includes/admin/class-wcs-admin-post-types.php:446 #: includes/wcs-user-functions.php:272 msgid "Reactivate" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:366 +#: includes/admin/class-wcs-admin-post-types.php:447 #: includes/wcs-user-functions.php:267 msgid "Suspend" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:368 -#: includes/admin/class-wcs-admin-post-types.php:383 +#: includes/admin/class-wcs-admin-post-types.php:449 +#: includes/admin/class-wcs-admin-post-types.php:464 msgid "Trash" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:369 -#: includes/admin/class-wcs-admin-post-types.php:387 +#: includes/admin/class-wcs-admin-post-types.php:450 +#: includes/admin/class-wcs-admin-post-types.php:468 msgid "Delete Permanently" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:381 -#: includes/class-wc-subscriptions-product.php:811 +#: includes/admin/class-wcs-admin-post-types.php:462 +#: includes/class-wc-subscriptions-product.php:797 msgid "Restore this item from the Trash" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:381 -#: includes/class-wc-subscriptions-product.php:812 +#: includes/admin/class-wcs-admin-post-types.php:462 +#: includes/class-wc-subscriptions-product.php:798 msgid "Restore" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:383 +#: includes/admin/class-wcs-admin-post-types.php:464 msgid "Move this item to the Trash" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:387 +#: includes/admin/class-wcs-admin-post-types.php:468 msgid "Delete this item permanently" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:393 +#: includes/admin/class-wcs-admin-post-types.php:474 msgid "Cancel Now" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:426 -#: templates/emails/plain/admin-new-renewal-order.php:54 -#: templates/emails/plain/customer-completed-renewal-order.php:52 -#: templates/emails/plain/customer-processing-renewal-order.php:51 +#: includes/admin/class-wcs-admin-post-types.php:507 #. translators: placeholder is customer's billing email msgid "Email: %s" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:431 -#: templates/emails/plain/admin-new-renewal-order.php:59 -#: templates/emails/plain/customer-completed-renewal-order.php:58 -#: templates/emails/plain/customer-processing-renewal-order.php:57 +#: includes/admin/class-wcs-admin-post-types.php:512 #. translators: placeholder is customer's billing phone number msgid "Tel: %s" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:463 +#: includes/admin/class-wcs-admin-post-types.php:544 msgid "Show more details" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:507 +#: includes/admin/class-wcs-admin-post-types.php:587 msgid "%d item" msgid_plural "%d items" msgstr[0] "" msgstr[1] "" -#: includes/admin/class-wcs-admin-post-types.php:542 +#: includes/admin/class-wcs-admin-post-types.php:631 #: templates/myaccount/my-subscriptions.php:48 #. translators: placeholder is the display name of a payment gateway a #. subscription was paid by msgid "Via %s" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:553 +#: includes/admin/class-wcs-admin-post-types.php:642 msgid "Y/m/d g:i:s A" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:556 +#: includes/admin/class-wcs-admin-post-types.php:645 msgid "" "This date should be treated as an estimate only. The payment gateway for " "this subscription controls when payments are processed." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:829 -#: includes/admin/class-wcs-admin-post-types.php:832 -#: includes/admin/class-wcs-admin-post-types.php:835 +#: includes/admin/class-wcs-admin-post-types.php:919 +#: includes/admin/class-wcs-admin-post-types.php:922 +#: includes/admin/class-wcs-admin-post-types.php:925 msgid "Subscription updated." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:830 +#: includes/admin/class-wcs-admin-post-types.php:920 msgid "Custom field updated." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:831 +#: includes/admin/class-wcs-admin-post-types.php:921 msgid "Custom field deleted." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:836 +#: includes/admin/class-wcs-admin-post-types.php:926 msgid "Subscription saved." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:837 +#: includes/admin/class-wcs-admin-post-types.php:927 msgid "Subscription submitted." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:839 +#: includes/admin/class-wcs-admin-post-types.php:929 #. translators: php date string msgid "Subscription scheduled for: %1$s." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:840 +#: includes/admin/class-wcs-admin-post-types.php:930 msgid "Subscription draft updated." msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:878 +#: includes/admin/class-wcs-admin-post-types.php:968 msgid "Any Payment Method" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:879 +#: includes/admin/class-wcs-admin-post-types.php:969 msgid "None" msgstr "" +#: includes/admin/class-wcs-admin-reports.php:58 +msgid "Subscription Events by Date" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:64 +msgid "Upcoming Recurring Revenue" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:70 +msgid "Retention Rate" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:76 +msgid "Subscriptions by Product" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:82 +msgid "Subscriptions by Customer" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:92 +msgid "Failed Payment Retries" +msgstr "" + +#: includes/admin/class-wcs-admin-reports.php:132 +#: includes/admin/reports/class-wcs-report-cache-manager.php:257 +msgid "WooCommerce" +msgstr "" + #: includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php:54 msgid "Customer:" msgstr "" @@ -715,7 +721,7 @@ msgid "Search for a customer…" msgstr "" #: includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php:80 -msgid "Subscription Status:" +msgid "Subscription status:" msgstr "" #: includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php:98 @@ -762,20 +768,8 @@ msgstr "" msgid "Error updating some information: %s" msgstr "" -#: includes/admin/meta-boxes/views/html-related-orders-row.php:34 -#: includes/class-wc-subscription.php:681 -#: includes/class-wc-subscriptions-manager.php:2328 -#. translators: placeholder is human time diff (e.g. "3 weeks") -msgid "In %s" -msgstr "" - -#: includes/admin/meta-boxes/views/html-related-orders-row.php:37 -#: includes/class-wc-subscription.php:684 -#. translators: placeholder is human time diff (e.g. "3 weeks") -msgid "%s ago" -msgstr "" - -#: includes/admin/meta-boxes/views/html-related-orders-row.php:43 +#: includes/admin/meta-boxes/views/html-related-orders-row.php:29 +#: includes/admin/meta-boxes/views/html-retries-table.php:47 msgid "Unpublished" msgstr "" @@ -789,16 +783,70 @@ msgid "Relationship" msgstr "" #: includes/admin/meta-boxes/views/html-related-orders-table.php:19 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:515 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:173 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:197 #: templates/myaccount/related-orders.php:23 #: templates/myaccount/related-orders.php:41 msgid "Date" msgstr "" +#: includes/admin/meta-boxes/views/html-retries-table.php:17 +msgid "Retry Date" +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:19 +msgid "Retry Status" +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:20 +msgid "" +"The status of the automatic payment retry: pending means the retry will be " +"processed in the future, failed means the payment was not successful when " +"retried and completed means the payment succeeded when retried." +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:23 +msgid "Status of Order" +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:24 +msgid "" +"The status applied to the order for the time between when the renewal " +"payment failed or last retry occurred and when this retry was processed." +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:27 +msgid "Status of Subscription" +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:28 +msgid "" +"The status applied to the subscription for the time between when the " +"renewal payment failed or last retry occurred and when this retry was " +"processed." +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:31 +msgid "Email" +msgstr "" + +#: includes/admin/meta-boxes/views/html-retries-table.php:32 +msgid "" +"The email sent to the customer when the renewal payment or payment retry " +"failed to notify them that the payment would be retried." +msgstr "" + #: includes/admin/meta-boxes/views/html-subscription-schedule.php:22 #: includes/admin/meta-boxes/views/html-subscription-schedule.php:41 msgid "Recurring:" msgstr "" +#: includes/admin/meta-boxes/views/html-subscription-schedule.php:32 +#: templates/admin/deprecated/html-variation-price.php:57 +msgid "Billing Period" +msgstr "" + #: includes/admin/meta-boxes/views/html-subscription-schedule.php:60 msgid "Timezone:" msgstr "" @@ -807,122 +855,621 @@ msgstr "" msgid "Error: unable to find timezone of your browser." msgstr "" -#: includes/api/class-wc-api-subscriptions.php:102 wcs-functions.php:168 -msgid "Invalid subscription status given." +#: includes/admin/reports/class-wcs-report-cache-manager.php:260 +msgid "" +"Please note: data for this report is cached. The data displayed may be out " +"of date by up to 24 hours. The cache is updated each morning at 4am in your " +"site's timezone." msgstr "" -#: includes/api/class-wc-api-subscriptions.php:124 -msgid "You do not have permission to read the subscriptions count" +#: includes/admin/reports/class-wcs-report-dashboard.php:78 +msgid "%s signup subscription signups this month" +msgid_plural "%s signups subscription signups this month" +msgstr[0] "" +msgstr[1] "" + +#: includes/admin/reports/class-wcs-report-dashboard.php:83 +msgid "%s renewal subscription renewals this month" +msgid_plural "%s renewals subscription renewals this month" +msgstr[0] "" +msgstr[1] "" + +#: includes/admin/reports/class-wcs-report-retention-rate.php:226 +msgid "Unended Subscription Count" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:173 -msgid "You do not have permission to create subscriptions" +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:22 +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:95 +msgid "Customer" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:239 -msgid "The requested subscription cannot be edited." +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:23 +msgid "Customers" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:304 +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:32 +msgid "No customers found." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:43 +msgid "Customer Totals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:44 +msgid "Total Subscribers" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:45 +msgid "Active Subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:46 +msgid "Total Subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:47 +msgid "Total Subscription Orders" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:48 +msgid "Average Lifetime Value" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:96 +msgid "Active Subscriptions %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:96 +msgid "" +"The number of subscriptions this customer has with a status of active or " +"pending cancellation." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:97 +msgid "Total Subscriptions %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:97 +msgid "" +"The number of subscriptions this customer has with a status other than " +"pending or trashed." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:98 +msgid "Total Subscription Orders %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:98 +msgid "" +"The number of sign-up, switch and renewal orders this customer has placed " +"with your store with a paid status (i.e. processing or complete)." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:99 +msgid "Lifetime Value from Subscriptions %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-customer.php:99 +msgid "The total value of this customer's sign-up, switch and renewal orders." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:20 +msgid "Product" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:21 +msgid "Products" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:30 +msgid "No products found." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:84 +msgid "Subscription Product" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:85 +msgid "Subscription Count %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:85 +msgid "" +"The number of subscriptions that include this product as a line item and " +"have a status other than pending or trashed." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:86 +msgid "Average Recurring Line Total %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:86 +msgid "The average line total for this product on each subscription." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:87 +msgid "Average Lifetime Value %s" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:87 +msgid "The average line total on all orders for this product line item." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:246 +msgid "subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:364 +msgid "%s signup revenue in this period" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:365 +msgid "" +"The sum of all subscription parent orders, including other items, fees, tax " +"and shipping." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:371 +msgid "%s renewal revenue in this period" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:372 +msgid "The sum of all renewal orders including tax and shipping." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:378 +msgid "%s resubscribe revenue in this period" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:379 +msgid "The sum of all resubscribe orders including tax and shipping." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:385 +msgid "%s new subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:386 +msgid "" +"The number of subscriptions created during this period, either by being " +"manually created, imported or a customer placing an order." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:392 +msgid "%s subscription signups" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:393 +msgid "" +"The number of subscription parent orders created during this period. This " +"represents the new subscriptions created by customers placing an order via " +"checkout." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:399 +msgid "%s subscription resubscribes" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:400 +msgid "The number of resubscribe orders processed during this period." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:406 +msgid "%s subscription renewals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:407 +msgid "The number of renewal orders processed during this period." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:413 +msgid "%s subscription switches" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:414 +msgid "" +"The number of subscriptions upgraded, downgraded or cross-graded during " +"this period." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:420 +msgid "%s subscription cancellations" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:421 +msgid "" +"The number of subscriptions cancelled by the customer or store manager " +"during this period. The pre-paid term may not yet have ended during this " +"period." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:427 +msgid "%s subscriptions ended" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:428 +msgid "" +"The number of subscriptions which have either expired or reached the end of " +"the prepaid term if it was previously cancelled." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:434 +msgid "%s current subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:435 +msgid "" +"The number of subscriptions during this period with an end date in the " +"future and a status other than pending." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:451 +msgid "%s net subscription gain" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:453 +msgid "%s net subscription loss" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:458 +msgid "Change in subscriptions between the start and end of the period." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:472 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:137 +msgid "Year" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:473 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:138 +msgid "Last Month" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:474 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:139 +msgid "This Month" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:475 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:140 +msgid "Last 7 Days" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:519 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:177 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:201 +msgid "Export CSV" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:576 +msgid "Switched subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:592 +msgid "New Subscriptions" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:608 +msgid "Subscriptions signups" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:623 +msgid "Number of resubscribes" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:638 +msgid "Number of renewals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:670 +msgid "Subscriptions Ended" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:686 +msgid "Cancellations" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:701 +msgid "Signup Totals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:721 +msgid "Resubscribe Totals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:741 +msgid "Renewal Totals" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:95 +msgid "%s renewal revenue recovered" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:96 +msgid "" +"The total amount of revenue, including tax and shipping, recovered with the " +"failed payment retry system for renewal orders with a failed payment." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:102 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:86 +msgid "%s renewal orders" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:103 +msgid "" +"The number of renewal orders which had a failed payment use the retry " +"system." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:108 +msgid "%s retry attempts succeeded" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:109 +msgid "" +"The number of renewal payment retries for this period which were able to " +"process the payment which had previously failed one or more times." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:115 +msgid "%s retry attempts failed" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:116 +msgid "" +"The number of renewal payment retries for this period which did not result " +"in a successful payment." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:122 +msgid "%s retry attempts pending" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:123 +msgid "The number of renewal payment retries not yet processed." +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:225 +msgid "Successful retries" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:241 +msgid "Failed retries" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:257 +msgid "Pending retries" +msgstr "" + +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:273 +msgid "Recovered Renewal Revenue" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:81 +msgid "%s renewal income in this period" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:91 +msgid "%s average renewal amount" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:167 +msgid "Next 12 Months" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:168 +msgid "Next 30 Days" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:169 +msgid "Next Month" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:170 +msgid "Next 7 Days" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:235 +msgid "Renewals count" +msgstr "" + +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:244 +msgid "Renewals amount" +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:163 +msgid "Invalid subscription id." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:232 +msgid "Cannot create subscription: %s." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:275 +msgid "Updating subscription dates errored with message: %s" +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:294 +#: includes/api/legacy/class-wc-api-subscriptions.php:304 msgid "" "Gateway does not support admin changing the payment method on a " "Subscription." msgstr "" -#: includes/api/class-wc-api-subscriptions.php:342 +#: includes/api/class-wc-rest-subscriptions-controller.php:327 +#. translators: 1$: gateway id, 2$: error message +msgid "" +"Subscription payment method could not be set to %1$s with error message: " +"%2$s" +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:341 +msgid "The number of billing periods between subscription renewals." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:346 +msgid "Billing period for the subscription." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:352 +msgid "Subscription payment details." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:357 +msgid "Payment gateway ID." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:364 +msgid "The subscription's start date." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:369 +msgid "The subscription's trial date" +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:374 +msgid "The subscription's next payment date." +msgstr "" + +#: includes/api/class-wc-rest-subscriptions-controller.php:379 +msgid "The subscription's end date." +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:102 wcs-functions.php:170 +msgid "Invalid subscription status given." +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:124 +msgid "You do not have permission to read the subscriptions count" +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:173 +msgid "You do not have permission to create subscriptions" +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:239 +msgid "The requested subscription cannot be edited." +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:342 #. translators: 1$: gateway id, 2$: error message msgid "" "Subscription payment method could not be set to %1$s and has been set to " "manual with error message: %2$s" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:377 wcs-functions.php:142 +#: includes/api/legacy/class-wc-api-subscriptions.php:377 wcs-functions.php:144 msgid "" "Invalid subscription billing interval given. Must be an integer greater " "than 0." msgstr "" -#: includes/api/class-wc-api-subscriptions.php:389 wcs-functions.php:137 +#: includes/api/legacy/class-wc-api-subscriptions.php:389 wcs-functions.php:139 msgid "Invalid subscription billing period given." msgstr "" -#: includes/class-wc-subscription.php:309 -#: includes/class-wc-subscription.php:400 +#: includes/class-wc-subscription.php:305 msgid "Unable to change subscription status to \"%s\"." msgstr "" -#: includes/class-wc-subscription.php:382 +#: includes/class-wc-subscription.php:401 #. translators: $1 note why the status changes (if any), $2: old status, $3: #. new status msgid "%1$s Status changed from %2$s to %3$s." msgstr "" -#: includes/class-wc-subscription.php:691 +#: includes/class-wc-subscription.php:409 +msgid "Unable to change subscription status to \"%s\". Exception: %s" +msgstr "" + +#: includes/class-wc-subscription.php:697 +#: includes/class-wc-subscriptions-manager.php:2212 +#: includes/wcs-formatting-functions.php:228 +#. translators: placeholder is human time diff (e.g. "3 weeks") +msgid "In %s" +msgstr "" + +#: includes/class-wc-subscription.php:700 +#: includes/wcs-formatting-functions.php:231 +#. translators: placeholder is human time diff (e.g. "3 weeks") +msgid "%s ago" +msgstr "" + +#: includes/class-wc-subscription.php:707 msgid "Not yet ended" msgstr "" -#: includes/class-wc-subscription.php:734 +#: includes/class-wc-subscription.php:710 +msgid "Not cancelled" +msgstr "" + +#: includes/class-wc-subscription.php:753 msgid "Invalid format. First parameter needs to be an array." msgstr "" -#: includes/class-wc-subscription.php:738 +#: includes/class-wc-subscription.php:757 msgid "Invalid data. First parameter was empty when passed to update_dates()." msgstr "" -#: includes/class-wc-subscription.php:745 +#: includes/class-wc-subscription.php:764 msgid "" "Invalid data. First parameter has a date that is not in the registered date " "types." msgstr "" -#: includes/class-wc-subscription.php:793 +#: includes/class-wc-subscription.php:812 +msgid "The %s date must occur after the cancellation date." +msgstr "" + +#: includes/class-wc-subscription.php:817 msgid "The %s date must occur after the last payment date." msgstr "" -#: includes/class-wc-subscription.php:797 +#: includes/class-wc-subscription.php:821 msgid "The %s date must occur after the next payment date." msgstr "" -#: includes/class-wc-subscription.php:802 +#: includes/class-wc-subscription.php:826 msgid "The %s date must occur after the trial end date." msgstr "" -#: includes/class-wc-subscription.php:806 +#: includes/class-wc-subscription.php:830 msgid "The %s date must occur after the start date." msgstr "" -#: includes/class-wc-subscription.php:861 +#: includes/class-wc-subscription.php:883 msgid "The start date of a subscription can not be deleted, only updated." msgstr "" -#: includes/class-wc-subscription.php:864 +#: includes/class-wc-subscription.php:886 msgid "" "The last payment date of a subscription can not be deleted. You must delete " "the order." msgstr "" -#: includes/class-wc-subscription.php:1267 +#: includes/class-wc-subscription.php:1293 msgid "Sign-up complete." msgstr "" -#: includes/class-wc-subscription.php:1269 +#: includes/class-wc-subscription.php:1295 msgid "Payment received." msgstr "" -#: includes/class-wc-subscription.php:1300 +#: includes/class-wc-subscription.php:1326 msgid "Payment failed." msgstr "" -#: includes/class-wc-subscription.php:1304 +#: includes/class-wc-subscription.php:1330 msgid "Subscription Cancelled: maximum number of failed payments reached." msgstr "" -#: includes/class-wc-subscription.php:1499 +#: includes/class-wc-subscription.php:1525 #: includes/class-wcs-change-payment-method-admin.php:155 msgid "Manual Renewal" msgstr "" -#: includes/class-wc-subscription.php:1564 +#: includes/class-wc-subscription.php:1590 msgid "Payment method meta must be an array." msgstr "" @@ -942,28 +1489,26 @@ msgstr "" msgid "Update the %1$s used for %2$sall%3$s of my active subscriptions" msgstr "" -#: includes/class-wc-subscriptions-cart.php:836 +#: includes/class-wc-subscriptions-cart.php:832 msgid "Please enter a valid postcode/ZIP." msgstr "" -#: includes/class-wc-subscriptions-cart.php:1007 +#: includes/class-wc-subscriptions-cart.php:1003 msgid "" "That subscription product can not be added to your cart as it already " "contains a subscription renewal." msgstr "" -#: includes/class-wc-subscriptions-cart.php:1092 +#: includes/class-wc-subscriptions-cart.php:1088 msgid "Invalid recurring shipping method." msgstr "" -#: includes/class-wc-subscriptions-cart.php:2060 +#: includes/class-wc-subscriptions-cart.php:1865 msgid "now" msgstr "" #: includes/class-wc-subscriptions-change-payment-gateway.php:126 -#: templates/emails/plain/admin-new-switch-order.php:57 -#: templates/emails/plain/cancelled-subscription.php:20 -#: templates/emails/plain/customer-completed-switch-order.php:52 +#: templates/emails/plain/email-order-details.php:19 #. translators: placeholder is the subscription order number wrapped in #. tags msgid "Subscription Number: %s" @@ -1002,7 +1547,8 @@ msgid "Invalid Subscription." msgstr "" #: includes/class-wc-subscriptions-change-payment-gateway.php:197 -#: includes/class-wcs-cart-resubscribe.php:58 +#: includes/class-wcs-cart-resubscribe.php:76 +#: includes/class-wcs-cart-resubscribe.php:127 #: includes/class-wcs-user-change-status-handler.php:103 msgid "That doesn't appear to be one of your subscriptions." msgstr "" @@ -1098,7 +1644,7 @@ msgid "" msgstr "" #: includes/class-wc-subscriptions-manager.php:141 -#: includes/gateways/class-wc-subscriptions-payment-gateways.php:183 +#: includes/gateways/class-wc-subscriptions-payment-gateways.php:201 msgid "Subscription doesn't exist in scheduled action: %d" msgstr "" @@ -1156,50 +1702,66 @@ msgstr "" msgid "Change" msgstr "" -#: includes/class-wc-subscriptions-manager.php:2210 +#: includes/class-wc-subscriptions-manager.php:2094 #. translators: placeholder is subscription ID msgid "Failed sign-up for subscription %s." msgstr "" -#: includes/class-wc-subscriptions-manager.php:2301 +#: includes/class-wc-subscriptions-manager.php:2185 msgid "Invalid security token, please reload the page and try again." msgstr "" -#: includes/class-wc-subscriptions-manager.php:2305 +#: includes/class-wc-subscriptions-manager.php:2189 msgid "Only store managers can edit payment dates." msgstr "" -#: includes/class-wc-subscriptions-manager.php:2309 +#: includes/class-wc-subscriptions-manager.php:2193 msgid "Please enter all date fields." msgstr "" -#: includes/class-wc-subscriptions-manager.php:2334 +#: includes/class-wc-subscriptions-manager.php:2218 msgid "Date Changed" msgstr "" -#: includes/class-wc-subscriptions-order.php:362 +#: includes/class-wc-subscriptions-order.php:366 msgid "Your subscription will be activated when payment clears." msgid_plural "Your subscriptions will be activated when payment clears." msgstr[0] "" msgstr[1] "" -#: includes/class-wc-subscriptions-order.php:365 +#: includes/class-wc-subscriptions-order.php:375 #. translators: placeholders are opening and closing link tags msgid "View the status of your subscription in %syour account%s." msgid_plural "View the status of your subscriptions in %syour account%s." msgstr[0] "" msgstr[1] "" -#: includes/class-wc-subscriptions-order.php:635 -msgid "Show all types" +#: includes/class-wc-subscriptions-order.php:423 +msgid "Subscription Relationship" msgstr "" -#: includes/class-wc-subscriptions-order.php:874 +#: includes/class-wc-subscriptions-order.php:443 +msgid "Renewal Order" +msgstr "" + +#: includes/class-wc-subscriptions-order.php:445 +msgid "Resubscribe Order" +msgstr "" + +#: includes/class-wc-subscriptions-order.php:447 +msgid "Parent Order" +msgstr "" + +#: includes/class-wc-subscriptions-order.php:685 +msgid "All orders types" +msgstr "" + +#: includes/class-wc-subscriptions-order.php:952 #. translators: $1: opening link tag, $2: order number, $3: closing link tag msgid "Subscription cancelled for refunded order %1$s#%2$s%3$s." msgstr "" -#: includes/class-wc-subscriptions-product.php:351 +#: includes/class-wc-subscriptions-product.php:348 #: includes/wcs-formatting-functions.php:102 #: includes/wcs-formatting-functions.php:186 #. translators: 1$: recurring amount string, 2$: day of the week (e.g. "$10 @@ -1207,34 +1769,34 @@ msgstr "" msgid "%1$s every %2$s" msgstr "" -#: includes/class-wc-subscriptions-product.php:354 +#: includes/class-wc-subscriptions-product.php:351 #: includes/wcs-formatting-functions.php:111 #. translators: 1$: recurring amount string, 2$: period, 3$: day of the week #. (e.g. "$10 every 2nd week on Wednesday") msgid "%1$s every %2$s on %3$s" msgstr "" -#: includes/class-wc-subscriptions-product.php:361 +#: includes/class-wc-subscriptions-product.php:358 #: includes/wcs-formatting-functions.php:129 #. translators: placeholder is recurring amount msgid "%s on the last day of each month" msgstr "" -#: includes/class-wc-subscriptions-product.php:364 +#: includes/class-wc-subscriptions-product.php:361 #: includes/wcs-formatting-functions.php:132 #. translators: 1$: recurring amount, 2$: day of the month (e.g. "23rd") (e.g. #. "$5 every 23rd of each month") msgid "%1$s on the %2$s of each month" msgstr "" -#: includes/class-wc-subscriptions-product.php:369 +#: includes/class-wc-subscriptions-product.php:366 #: includes/wcs-formatting-functions.php:148 #. translators: 1$: recurring amount, 2$: interval (e.g. "3rd") (e.g. "$10 on #. the last day of every 3rd month") msgid "%1$s on the last day of every %2$s month" msgstr "" -#: includes/class-wc-subscriptions-product.php:372 +#: includes/class-wc-subscriptions-product.php:369 #: includes/wcs-formatting-functions.php:151 #. translators: 1$: on the, 2$: day of every, 3$: #. month (e.g. "$10 on the 23rd day of every 2nd month") @@ -1243,7 +1805,7 @@ msgstr "" msgid "%1$s on the %2$s day of every %3$s month" msgstr "" -#: includes/class-wc-subscriptions-product.php:379 +#: includes/class-wc-subscriptions-product.php:376 #: includes/wcs-formatting-functions.php:164 #. translators: 1$: on, 2$: , 3$: each year (e.g. "$15 on #. March 15th each year") @@ -1252,14 +1814,14 @@ msgstr "" msgid "%1$s on %2$s %3$s each year" msgstr "" -#: includes/class-wc-subscriptions-product.php:382 +#: includes/class-wc-subscriptions-product.php:379 #: includes/wcs-formatting-functions.php:173 #. translators: 1$: recurring amount, 2$: month (e.g. "March"), 3$: day of the #. month (e.g. "23rd") (e.g. "$15 on March 15th every 3rd year") msgid "%1$s on %2$s %3$s every %4$s year" msgstr "" -#: includes/class-wc-subscriptions-product.php:388 +#: includes/class-wc-subscriptions-product.php:385 #: includes/wcs-formatting-functions.php:184 #. translators: 1$: recurring amount, 2$: subscription period (e.g. "month" or #. "3 months") (e.g. "$15 / month" or "$15 every 2nd month") @@ -1268,25 +1830,25 @@ msgid_plural " %1$s every %2$s" msgstr[0] "" msgstr[1] "" -#: includes/class-wc-subscriptions-product.php:394 +#: includes/class-wc-subscriptions-product.php:391 #. translators: billing period (e.g. "every week") msgid "every %s" msgstr "" -#: includes/class-wc-subscriptions-product.php:400 +#: includes/class-wc-subscriptions-product.php:397 #: includes/wcs-formatting-functions.php:194 #. translators: 1$: subscription string (e.g. "$10 up front then $5 on March #. 23rd every 3rd year"), 2$: length (e.g. "4 years") msgid "%1$s for %2$s" msgstr "" -#: includes/class-wc-subscriptions-product.php:406 +#: includes/class-wc-subscriptions-product.php:403 #. translators: 1$: subscription string (e.g. "$15 on March 15th every 3 years #. for 6 years"), 2$: trial length (e.g.: "with 4 months free trial") msgid "%1$s with %2$s free trial" msgstr "" -#: includes/class-wc-subscriptions-product.php:411 +#: includes/class-wc-subscriptions-product.php:408 #. translators: 1$: subscription string (e.g. "$15 on March 15th every 3 years #. for 6 years with 2 months free trial"), 2$: signup fee price (e.g. "and a #. $30 sign-up fee") @@ -1302,18 +1864,18 @@ msgstr "" msgid "Subscription renewal orders cannot be cancelled." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:155 +#: includes/class-wc-subscriptions-switcher.php:154 msgid "" "You have a subscription to this product. Choosing a new subscription will " "replace your existing subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:157 +#: includes/class-wc-subscriptions-switcher.php:156 msgid "Choose a new subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:179 -#: includes/class-wc-subscriptions-switcher.php:857 +#: includes/class-wc-subscriptions-switcher.php:178 +#: includes/class-wc-subscriptions-switcher.php:902 msgid "" "Your cart contained an invalid subscription switch request. It has been " "removed." @@ -1329,7 +1891,7 @@ msgid "" "customer. You can not purchase the product again." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:232 +#: includes/class-wc-subscriptions-switcher.php:229 #. translators: 1$: is the "You have already subscribed to this product" #. notice, 2$-4$: opening/closing link tags, 3$: an order number msgid "" @@ -1337,107 +1899,122 @@ msgid "" "subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:318 +#: includes/class-wc-subscriptions-switcher.php:308 msgid "Switching" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:321 +#: includes/class-wc-subscriptions-switcher.php:311 #. translators: placeholders are opening and closing link tags msgid "" "Allow subscribers to switch (upgrade or downgrade) between different " "subscriptions. %sLearn more%s." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:326 +#: includes/class-wc-subscriptions-switcher.php:316 msgid "Allow Switching" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:327 +#: includes/class-wc-subscriptions-switcher.php:317 msgid "" "Allow subscribers to switch between subscriptions combined in a grouped " "product, different variations of a Variable subscription or don't allow " "switching." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:343 +#: includes/class-wc-subscriptions-switcher.php:333 msgid "Prorate Recurring Payment" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:344 +#: includes/class-wc-subscriptions-switcher.php:334 msgid "" "When switching to a subscription with a different recurring payment or " "billing period, should the price paid for the existing billing period be " "prorated when switching to the new subscription?" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:361 +#: includes/class-wc-subscriptions-switcher.php:351 msgid "Prorate Sign up Fee" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:362 +#: includes/class-wc-subscriptions-switcher.php:352 msgid "" "When switching to a subscription with a sign up fee, you can require the " "customer pay only the gap between the existing subscription's sign up fee " "and the new subscription's sign up fee (if any)." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:377 +#: includes/class-wc-subscriptions-switcher.php:367 msgid "Prorate Subscription Length" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:378 +#: includes/class-wc-subscriptions-switcher.php:368 msgid "" "When switching to a subscription with a length, you can take into account " "the payments already completed by the customer when determining how many " "payments the subscriber needs to make for the new subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:393 +#: includes/class-wc-subscriptions-switcher.php:383 msgid "Switch Button Text" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:394 +#: includes/class-wc-subscriptions-switcher.php:384 msgid "" "Customise the text displayed on the button next to the subscription on the " "subscriber's account page. The default is \"Switch Subscription\", but you " "may wish to change this to \"Upgrade\" or \"Change Subscription\"." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:398 -#: includes/class-wc-subscriptions-switcher.php:424 -#: includes/class-wc-subscriptions-switcher.php:1878 +#: includes/class-wc-subscriptions-switcher.php:388 +#: includes/class-wc-subscriptions-switcher.php:414 +#: includes/class-wc-subscriptions-switcher.php:2112 msgid "Upgrade or Downgrade" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:810 +#: includes/class-wc-subscriptions-switcher.php:765 +msgid "Switch order cancelled due to a new switch order being created #%s." +msgstr "" + +#: includes/class-wc-subscriptions-switcher.php:855 msgid "Switch Order" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:825 +#: includes/class-wc-subscriptions-switcher.php:870 msgid "Switched Subscription" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:925 +#: includes/class-wc-subscriptions-switcher.php:969 +msgid "You can only switch to a subscription product." +msgstr "" + +#: includes/class-wc-subscriptions-switcher.php:975 msgid "We can not find your old subscription item." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:947 +#: includes/class-wc-subscriptions-switcher.php:997 msgid "You can not switch to the same subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:994 +#: includes/class-wc-subscriptions-switcher.php:1044 msgid "" "You can not switch this subscription. It appears you do not own the " "subscription." msgstr "" -#: includes/class-wc-subscriptions-switcher.php:1029 +#: includes/class-wc-subscriptions-switcher.php:1079 msgid "There was an error locating the switch details." msgstr "" +#: includes/class-wc-subscriptions-switcher.php:1814 +msgid "The original subscription item being switched cannot be found." +msgstr "" + +#: includes/class-wc-subscriptions-switcher.php:1867 +msgid "Failed to update the subscription shipping method." +msgstr "" + #: includes/class-wc-subscriptions-synchroniser.php:47 -#: templates/admin/deprecated/html-variation-synchronisation.php:30 -msgid "Synchronise Renewals" +msgid "Synchronise renewals" msgstr "" #: includes/class-wc-subscriptions-synchroniser.php:48 @@ -1464,35 +2041,39 @@ msgid "" "year, charge a prorated amount for the subscription at the time of sign up." msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:607 +#: includes/class-wc-subscriptions-synchroniser.php:237 +msgid "Month for Synchronisation" +msgstr "" + +#: includes/class-wc-subscriptions-synchroniser.php:603 msgid "Do not synchronise" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:615 +#: includes/class-wc-subscriptions-synchroniser.php:611 #. translators: placeholder is a day of the week msgid "%s each week" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:621 +#: includes/class-wc-subscriptions-synchroniser.php:617 #. translators: placeholder is a number of day with language specific suffix #. applied (e.g. "1st", "3rd", "5th", etc...) msgid "%s day of the month" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:623 +#: includes/class-wc-subscriptions-synchroniser.php:619 msgid "Last day of the month" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:671 +#: includes/class-wc-subscriptions-synchroniser.php:667 msgid "Today!" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:678 +#: includes/class-wc-subscriptions-synchroniser.php:674 #. translators: placeholder is a date msgid "First payment prorated. Next payment: %s" msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:681 +#: includes/class-wc-subscriptions-synchroniser.php:677 #. translators: placeholder is a date msgid "First payment: %s" msgstr "" @@ -1509,23 +2090,28 @@ msgstr "" msgid "View and manage subscriptions" msgstr "" -#: includes/class-wcs-cart-initial-payment.php:48 +#: includes/class-wcs-cart-initial-payment.php:56 +#: includes/class-wcs-cart-renewal.php:121 msgid "That doesn't appear to be your order." msgstr "" -#: includes/class-wcs-cart-renewal.php:162 +#: includes/class-wcs-cart-renewal.php:149 +msgid "Complete checkout to renew your subscription." +msgstr "" + +#: includes/class-wcs-cart-renewal.php:188 #. translators: placeholder is an item name msgid "" "The %s product has been deleted and can no longer be renewed. Please choose " "a new product or contact us for assistance." msgstr "" -#: includes/class-wcs-cart-renewal.php:191 +#: includes/class-wcs-cart-renewal.php:221 #. translators: %s is subscription's number msgid "Subscription #%s has not been added to the cart." msgstr "" -#: includes/class-wcs-cart-renewal.php:317 +#: includes/class-wcs-cart-renewal.php:347 msgid "" "We couldn't find the original subscription for an item in your cart. The " "item was removed." @@ -1535,7 +2121,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: includes/class-wcs-cart-renewal.php:324 +#: includes/class-wcs-cart-renewal.php:354 msgid "" "We couldn't find the original renewal order for an item in your cart. The " "item was removed." @@ -1545,33 +2131,60 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: includes/class-wcs-cart-renewal.php:540 +#: includes/class-wcs-cart-renewal.php:613 msgid "All linked subscription items have been removed from the cart." msgstr "" -#: includes/class-wcs-cart-resubscribe.php:50 +#: includes/class-wcs-cart-resubscribe.php:68 msgid "There was an error with your request to resubscribe. Please try again." msgstr "" -#: includes/class-wcs-cart-resubscribe.php:54 +#: includes/class-wcs-cart-resubscribe.php:72 msgid "That subscription does not exist. Has it been deleted?" msgstr "" -#: includes/class-wcs-cart-resubscribe.php:62 +#: includes/class-wcs-cart-resubscribe.php:80 msgid "" "You can not resubscribe to that subscription. Please contact us if you need " "assistance." msgstr "" -#: includes/class-wcs-cart-resubscribe.php:71 -#: includes/class-wcs-cart-resubscribe.php:88 +#: includes/class-wcs-cart-resubscribe.php:89 +#: includes/class-wcs-cart-resubscribe.php:117 msgid "Complete checkout to resubscribe." msgstr "" +#: includes/class-wcs-cart-resubscribe.php:310 +msgid "Customer resubscribed in order #%s" +msgstr "" + #: includes/class-wcs-change-payment-method-admin.php:113 msgid "Please choose a valid payment gateway to change to." msgstr "" +#: includes/class-wcs-limiter.php:46 +msgid "Limit subscription" +msgstr "" + +#: includes/class-wcs-limiter.php:48 +#. translators: placeholders are opening and closing link tags +msgid "" +"Only allow a customer to have one subscription to this product. %sLearn " +"more%s." +msgstr "" + +#: includes/class-wcs-limiter.php:50 +msgid "Do not limit" +msgstr "" + +#: includes/class-wcs-limiter.php:51 +msgid "Limit to one active subscription" +msgstr "" + +#: includes/class-wcs-limiter.php:52 +msgid "Limit to one of any status" +msgstr "" + #: includes/class-wcs-remove-item.php:106 msgid "Your request to undo your previous action was unsuccessful." msgstr "" @@ -1624,18 +2237,22 @@ msgid "" "assistance." msgstr "" -#: includes/class-wcs-webhooks.php:83 +#: includes/class-wcs-webhooks.php:90 msgid " Subscription Created" msgstr "" -#: includes/class-wcs-webhooks.php:84 +#: includes/class-wcs-webhooks.php:91 msgid " Subscription Updated" msgstr "" -#: includes/class-wcs-webhooks.php:85 +#: includes/class-wcs-webhooks.php:92 msgid " Subscription Deleted" msgstr "" +#: includes/class-wcs-webhooks.php:93 +msgid " Subscription Switched" +msgstr "" + #: includes/emails/class-wcs-email-cancelled-subscription.php:27 msgid "Cancelled Subscription" msgstr "" @@ -1650,31 +2267,41 @@ msgstr "" msgid "Subscription Cancelled" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:122 -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:176 +#: includes/emails/class-wcs-email-cancelled-subscription.php:128 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:183 +#: includes/emails/class-wcs-email-expired-subscription.php:126 +#: includes/emails/class-wcs-email-on-hold-subscription.php:126 msgid "Enable this email notification" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:129 +#: includes/emails/class-wcs-email-cancelled-subscription.php:135 +#: includes/emails/class-wcs-email-expired-subscription.php:133 +#: includes/emails/class-wcs-email-on-hold-subscription.php:133 #. translators: placeholder is admin email msgid "" "Enter recipients (comma separated) for this email. Defaults to " "%s." msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:136 +#: includes/emails/class-wcs-email-cancelled-subscription.php:142 +#: includes/emails/class-wcs-email-expired-subscription.php:140 +#: includes/emails/class-wcs-email-on-hold-subscription.php:140 msgid "" "This controls the email subject line. Leave blank to use the default " "subject: %s." msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:143 +#: includes/emails/class-wcs-email-cancelled-subscription.php:149 +#: includes/emails/class-wcs-email-expired-subscription.php:147 +#: includes/emails/class-wcs-email-on-hold-subscription.php:147 msgid "" "This controls the main heading contained within the email notification. " "Leave blank to use the default heading: %s." msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:150 +#: includes/emails/class-wcs-email-cancelled-subscription.php:156 +#: includes/emails/class-wcs-email-expired-subscription.php:154 +#: includes/emails/class-wcs-email-on-hold-subscription.php:154 msgid "Choose which format of email to send." msgstr "" @@ -1717,6 +2344,27 @@ msgid "" "download your files" msgstr "" +#: includes/emails/class-wcs-email-customer-payment-retry.php:27 +msgid "Customer Payment Retry" +msgstr "" + +#: includes/emails/class-wcs-email-customer-payment-retry.php:28 +msgid "" +"Sent to a customer when an attempt to automatically process a subscription " +"renewal payment has failed and a retry rule has been applied to retry the " +"payment in the future. The email contains the renewal order information, " +"date of the scheduled retry and payment links to allow the customer to pay " +"for the renewal order manually instead of waiting for the automatic retry." +msgstr "" + +#: includes/emails/class-wcs-email-customer-payment-retry.php:35 +msgid "Automatic payment failed for {order_number}, we will retry {retry_time}" +msgstr "" + +#: includes/emails/class-wcs-email-customer-payment-retry.php:36 +msgid "Automatic payment failed for order {order_number}" +msgstr "" + #: includes/emails/class-wcs-email-customer-processing-renewal-order.php:24 msgid "Processing Renewal order" msgstr "" @@ -1736,26 +2384,44 @@ msgstr "" msgid "Your {blogname} renewal order receipt from {order_date}" msgstr "" -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:27 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:31 msgid "Customer Renewal Invoice" msgstr "" -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:28 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:32 msgid "" "Sent to a customer when the subscription is due for renewal and the renewal " "requires a manual payment, either because it uses manual renewals or the " -"automatic recurring payment failed. The email contains renewal order " -"information and payment links." +"automatic recurring payment failed for the initial attempt and all " +"automatic retries (if any). The email contains renewal order information " +"and payment links." msgstr "" -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:35 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:39 msgid "Invoice for renewal order {order_number} from {order_date}" msgstr "" -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:36 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:40 msgid "Invoice for renewal order {order_number}" msgstr "" +#: includes/emails/class-wcs-email-expired-subscription.php:27 +msgid "Expired Subscription" +msgstr "" + +#: includes/emails/class-wcs-email-expired-subscription.php:28 +msgid "Expired Subscription emails are sent when a customer's subscription expires." +msgstr "" + +#: includes/emails/class-wcs-email-expired-subscription.php:30 +msgid "Subscription Expired" +msgstr "" + +#: includes/emails/class-wcs-email-expired-subscription.php:59 +#: includes/emails/class-wcs-email-on-hold-subscription.php:59 +msgid "Subscription argument passed in is not an object." +msgstr "" + #: includes/emails/class-wcs-email-new-renewal-order.php:22 msgid "New Renewal Order" msgstr "" @@ -1789,6 +2455,41 @@ msgstr "" msgid "[{blogname}] Subscription Switched ({order_number}) - {order_date}" msgstr "" +#: includes/emails/class-wcs-email-on-hold-subscription.php:27 +msgid "Suspended Subscription" +msgstr "" + +#: includes/emails/class-wcs-email-on-hold-subscription.php:28 +msgid "" +"Suspended Subscription emails are sent when a customer manually suspends " +"their subscription." +msgstr "" + +#: includes/emails/class-wcs-email-on-hold-subscription.php:30 +msgid "Subscription Suspended" +msgstr "" + +#: includes/emails/class-wcs-email-payment-retry.php:26 +msgid "Payment Retry" +msgstr "" + +#: includes/emails/class-wcs-email-payment-retry.php:27 +msgid "" +"Payment retry emails are sent to chosen recipient(s) when an attempt to " +"automatically process a subscription renewal payment has failed and a retry " +"rule has been applied to retry the payment in the future." +msgstr "" + +#: includes/emails/class-wcs-email-payment-retry.php:29 +msgid "Automatic renewal payment failed" +msgstr "" + +#: includes/emails/class-wcs-email-payment-retry.php:30 +msgid "" +"[{site_title}] Automatic payment failed for {order_number}, retry scheduled " +"to run {retry_time}" +msgstr "" + #: includes/gateways/class-wc-subscriptions-payment-gateways.php:126 msgid "" "Sorry, it seems there are no available payment methods which support " @@ -1796,35 +2497,35 @@ msgid "" "alternate arrangements." msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:199 +#: includes/gateways/paypal/class-wcs-paypal.php:204 msgid "Unable to find order for PayPal billing agreement." msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:256 +#: includes/gateways/paypal/class-wcs-paypal.php:261 msgid "An error occurred, please try again or try an alternate form of payment." msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:359 +#: includes/gateways/paypal/class-wcs-paypal.php:368 #. translators: placeholders are PayPal API error code and PayPal API error #. message msgid "PayPal API error: (%d) %s" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:364 +#: includes/gateways/paypal/class-wcs-paypal.php:373 #. translators: placeholder is PayPal transaction status message msgid "PayPal Transaction Held: %s" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:376 +#: includes/gateways/paypal/class-wcs-paypal.php:385 #. translators: placeholder is PayPal transaction status message msgid "PayPal payment declined: %s" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:380 +#: includes/gateways/paypal/class-wcs-paypal.php:389 msgid "PayPal payment approved (ID: %s)" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:433 +#: includes/gateways/paypal/class-wcs-paypal.php:442 msgid "" "Are you sure you want to change the payment method from PayPal standard?\n" "\n" @@ -1866,7 +2567,7 @@ msgstr "" #: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:151 #. translators: placeholders are link opening and closing tags. 1$-2$: to -#. gateway settings, 3$-4$: support docs on woothemes.com +#. gateway settings, 3$-4$: support docs on woocommerce.com msgid "" "There is a problem with PayPal. Your API credentials may be incorrect. " "Please update your %1$sAPI credentials%2$s. %3$sLearn more%4$s." @@ -1880,7 +2581,24 @@ msgid "" "subscription IDs. %1$sLearn more%2$s. %3$sDismiss%4$s." msgstr "" -#: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:243 +#: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:178 +msgid "" +"%sA fatal error has occurred when processing a recent subscription payment " +"with PayPal. Please %sopen a new ticket at WooThemes Support%s immediately " +"to get this resolved.%sIn order to get the quickest possible response " +"please attach a %sTemporary Admin Login%s and a copy of your PHP error logs " +"to your support ticket.%sLast recorded error: %s" +msgstr "" + +#: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:186 +msgid "Ignore this error (not recommended!)" +msgstr "" + +#: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:186 +msgid "Open up a ticket now!" +msgstr "" + +#: includes/gateways/paypal/includes/admin/class-wcs-paypal-admin.php:265 msgid "PayPal Subscription ID:" msgstr "" @@ -1897,7 +2615,7 @@ msgstr "" msgid "SKU: %s" msgstr "" -#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php:120 +#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response-payment.php:119 #. translators: placeholder is localised datetime msgid "expected clearing date %s" msgstr "" @@ -1943,13 +2661,112 @@ msgstr "" msgid "Subscription reactivated with PayPal" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:247 +#: includes/gateways/paypal/includes/class-wcs-paypal-status-manager.php:113 +msgid "PayPal API error - credentials are incorrect." +msgstr "" + +#: includes/payment-retry/class-wcs-retry-admin.php:46 +msgid "Automatic Failed Payment Retries" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-admin.php:97 +msgid "%d Pending Payment Retry" +msgid_plural "%d Pending Payment Retries" +msgstr[0] "" +msgstr[1] "" + +#: includes/payment-retry/class-wcs-retry-admin.php:100 +msgid "%d Processing Payment Retry" +msgid_plural "%d Processing Payment Retries" +msgstr[0] "" +msgstr[1] "" + +#: includes/payment-retry/class-wcs-retry-admin.php:103 +msgid "%d Failed Payment Retry" +msgid_plural "%d Failed Payment Retries" +msgstr[0] "" +msgstr[1] "" + +#: includes/payment-retry/class-wcs-retry-admin.php:106 +msgid "%d Successful Payment Retry" +msgid_plural "%d Successful Payment Retries" +msgstr[0] "" +msgstr[1] "" + +#: includes/payment-retry/class-wcs-retry-admin.php:109 +msgid "%d Cancelled Payment Retry" +msgid_plural "%d Cancelled Payment Retries" +msgstr[0] "" +msgstr[1] "" + +#: includes/payment-retry/class-wcs-retry-admin.php:133 +msgid "Retry Failed Payments" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-admin.php:134 +msgid "Enable automatic retry of failed recurring payments" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-admin.php:138 +msgid "" +"Attempt to recover recurring revenue that would otherwise be lost due to " +"payment methods being declined only temporarily. %sLearn more%s." +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:23 +msgid "" +"Payment retry posts store details about the automatic retry of failed " +"renewal payments." +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:34 +msgid "Renewal Payment Retry" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:36 +msgid "Add" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:37 +msgid "Add New Retry" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:38 +msgid "Edit" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:39 +msgid "Edit Retry" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:40 +msgid "New Retry" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:41 +#: includes/payment-retry/class-wcs-retry-post-store.php:42 +msgid "View Retry" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:43 +msgid "Search Renewal Payment Retries" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:44 +msgid "No retries found" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:45 +msgid "No retries found in trash" +msgstr "" + +#: includes/upgrades/class-wc-subscriptions-upgrader.php:276 #. translators: placeholder is a list of version numbers (e.g. "1.3 & 1.4 & #. 1.5") msgid "Database updated to version %s" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:270 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:299 #. translators: 1$: number of action scheduler hooks upgraded, 2$: #. "{execution_time}", will be replaced on front end with actual time msgid "" @@ -1957,79 +2774,83 @@ msgid "" "seconds)." msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:286 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:315 #. translators: 1$: number of subscriptions upgraded, 2$: "{execution_time}", #. will be replaced on front end with actual time it took msgid "Migrated %1$s subscriptions to the new structure (in %2$s seconds)." msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:299 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:328 #. translators: 1$: error message, 2$: opening link tag, 3$: closing link tag msgid "" "Unable to upgrade subscriptions.
Error: %1$s
Please refresh the " "page and try again. If problem persists, %2$scontact support%3$s." msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:554 -msgid "Welcome to WooCommerce Subscriptions 2.0" +#: includes/upgrades/class-wc-subscriptions-upgrader.php:583 +msgid "Welcome to WooCommerce Subscriptions 2.1" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:554 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:583 msgid "About WooCommerce Subscriptions" msgstr "" -#: includes/upgrades/templates/wcs-about.php:20 +#: includes/upgrades/templates/wcs-about-2-0.php:20 msgid "Welcome to Subscriptions 2.0" msgstr "" -#: includes/upgrades/templates/wcs-about.php:23 +#: includes/upgrades/templates/wcs-about-2-0.php:23 +#: includes/upgrades/templates/wcs-about.php:22 msgid "Thank you for updating to the latest version of WooCommerce Subscriptions." msgstr "" -#: includes/upgrades/templates/wcs-about.php:24 +#: includes/upgrades/templates/wcs-about-2-0.php:24 msgid "" "Version 2.0 has been in development for more than a year. We've reinvented " "the extension to take into account 3 years of feedback from store managers." msgstr "" -#: includes/upgrades/templates/wcs-about.php:25 +#: includes/upgrades/templates/wcs-about-2-0.php:25 +#: includes/upgrades/templates/wcs-about.php:24 msgid "We hope you enjoy it!" msgstr "" -#: includes/upgrades/templates/wcs-about.php:31 +#: includes/upgrades/templates/wcs-about-2-0.php:31 +#: includes/upgrades/templates/wcs-about.php:30 #. translators: placeholder is version number msgid "Version %s" msgstr "" -#: includes/upgrades/templates/wcs-about.php:42 +#: includes/upgrades/templates/wcs-about-2-0.php:42 +#: includes/upgrades/templates/wcs-about.php:41 msgid "Check Out What's New" msgstr "" -#: includes/upgrades/templates/wcs-about.php:51 +#: includes/upgrades/templates/wcs-about-2-0.php:51 msgid "Multiple Subscriptions" msgstr "" -#: includes/upgrades/templates/wcs-about.php:52 +#: includes/upgrades/templates/wcs-about-2-0.php:52 msgid "It's now easier for your customers to buy more subscriptions!" msgstr "" -#: includes/upgrades/templates/wcs-about.php:53 +#: includes/upgrades/templates/wcs-about-2-0.php:53 msgid "" "Customers can now purchase different subscription products in one " "transaction. The products can bill on any schedule and have any combination " "of sign-up fees and/or free trials." msgstr "" -#: includes/upgrades/templates/wcs-about.php:56 +#: includes/upgrades/templates/wcs-about-2-0.php:56 #. translators: placeholders are opening and closing link tags msgid "Learn more about the new %smultiple subscriptions%s feature." msgstr "" -#: includes/upgrades/templates/wcs-about.php:68 +#: includes/upgrades/templates/wcs-about-2-0.php:68 msgid "New Add/Edit Subscription Screen" msgstr "" -#: includes/upgrades/templates/wcs-about.php:69 +#: includes/upgrades/templates/wcs-about-2-0.php:69 msgid "" "Subscriptions v2.0 introduces a new administration interface to add or edit " "a subscription. You can make all the familiar changes, like modifying " @@ -2038,7 +2859,7 @@ msgid "" "adding a product line item." msgstr "" -#: includes/upgrades/templates/wcs-about.php:72 +#: includes/upgrades/templates/wcs-about-2-0.php:72 #. translators: placeholders are opening and closing tags msgid "" "The new interface is also built on the existing %sEdit Order%s screen. If " @@ -2046,7 +2867,7 @@ msgid "" "subscription." msgstr "" -#: includes/upgrades/templates/wcs-about.php:76 +#: includes/upgrades/templates/wcs-about-2-0.php:76 #. translators: placeholers are link tags: 1$-2$ new subscription page, 3$-4$: #. docs on woothemes msgid "" @@ -2054,11 +2875,11 @@ msgid "" "interface." msgstr "" -#: includes/upgrades/templates/wcs-about.php:87 +#: includes/upgrades/templates/wcs-about-2-0.php:87 msgid "New View Subscription Page" msgstr "" -#: includes/upgrades/templates/wcs-about.php:91 +#: includes/upgrades/templates/wcs-about-2-0.php:91 #. translators: placeholders are opening and closing tags msgid "" "Your customers can now view the full details of a subscription, including " @@ -2066,19 +2887,19 @@ msgid "" "orders, from a special %sMy Account > View Subscription%s page." msgstr "" -#: includes/upgrades/templates/wcs-about.php:93 +#: includes/upgrades/templates/wcs-about-2-0.php:93 msgid "" "This new page is also where the customer can suspend or cancel their " "subscription, change payment method, change shipping address or " "upgrade/downgrade an item." msgstr "" -#: includes/upgrades/templates/wcs-about.php:97 +#: includes/upgrades/templates/wcs-about-2-0.php:97 #. translators: placeholders are opening and closing link tags msgid "Learn more about the new %sView Subscription page%s." msgstr "" -#: includes/upgrades/templates/wcs-about.php:111 +#: includes/upgrades/templates/wcs-about-2-0.php:111 #. translators: placeholders are for opening and closing link () tags msgid "" "By default, adding new files to an existing subscription product will " @@ -2087,14 +2908,24 @@ msgid "" "subscribers with access to new files only after the next renewal payment." msgstr "" -#: includes/upgrades/templates/wcs-about.php:115 -#: includes/upgrades/templates/wcs-about.php:128 -#: includes/upgrades/templates/wcs-about.php:141 +#: includes/upgrades/templates/wcs-about-2-0.php:115 +#: includes/upgrades/templates/wcs-about-2-0.php:128 +#: includes/upgrades/templates/wcs-about-2-0.php:141 +#: includes/upgrades/templates/wcs-about.php:120 +#: includes/upgrades/templates/wcs-about.php:131 +#: includes/upgrades/templates/wcs-about.php:142 +#: includes/upgrades/templates/wcs-about.php:170 +#: includes/upgrades/templates/wcs-about.php:191 #. translators: placeholders are for opening and closing link () tags +#. translators: placeholders are for opening and closing link () tags +#. translators: placeholders are opening and closing anchor tags linking to +#. documentation +#. translators: placeholders are opening and closing anchor tags linking to +#. documentation msgid "%sLearn more »%s" msgstr "" -#: includes/upgrades/templates/wcs-about.php:124 +#: includes/upgrades/templates/wcs-about-2-0.php:124 #. translators: placeholders are opening and closing tags msgid "" "For a store manager to change a subscription from automatic to manual " @@ -2104,11 +2935,11 @@ msgid "" "Subscription%s interface." msgstr "" -#: includes/upgrades/templates/wcs-about.php:134 +#: includes/upgrades/templates/wcs-about-2-0.php:134 msgid "Change Trial and End Dates" msgstr "" -#: includes/upgrades/templates/wcs-about.php:137 +#: includes/upgrades/templates/wcs-about-2-0.php:137 #. translators: placeholders are opening and closing tags msgid "" "It was already possible to change a subscription's next payment date, but " @@ -2117,52 +2948,53 @@ msgid "" "of these dates from the %sEdit Subscription%s screen." msgstr "" -#: includes/upgrades/templates/wcs-about.php:150 +#: includes/upgrades/templates/wcs-about-2-0.php:150 msgid "And much more..." msgstr "" -#: includes/upgrades/templates/wcs-about.php:157 +#: includes/upgrades/templates/wcs-about-2-0.php:157 +#: includes/upgrades/templates/wcs-about.php:151 msgid "Peek Under the Hood for Developers" msgstr "" -#: includes/upgrades/templates/wcs-about.php:158 +#: includes/upgrades/templates/wcs-about-2-0.php:158 msgid "" "Subscriptions 2.0 introduces a new architecture built on the WooCommerce " "Custom Order Types API." msgstr "" -#: includes/upgrades/templates/wcs-about.php:164 +#: includes/upgrades/templates/wcs-about-2-0.php:164 #. translators: placeholders are opening and closing code tags msgid "New %sshop_subscription%s Post Type" msgstr "" -#: includes/upgrades/templates/wcs-about.php:166 +#: includes/upgrades/templates/wcs-about-2-0.php:166 msgid "" "By making a subscription a Custom Order Type, a subscription is also now a " "custom post type. This makes it faster to query subscriptions and it uses a " "database schema that is as scalable as WordPress posts and pages." msgstr "" -#: includes/upgrades/templates/wcs-about.php:169 +#: includes/upgrades/templates/wcs-about-2-0.php:169 #. translators: placeholders are opening and closing tags msgid "" "Developers can also now use all the familiar WordPress functions, like " "%sget_posts()%s, to query or modify subscription data." msgstr "" -#: includes/upgrades/templates/wcs-about.php:175 +#: includes/upgrades/templates/wcs-about-2-0.php:175 #. translators: placeholders are opening and closing tags msgid "New %sWC_Subscription%s Object" msgstr "" -#: includes/upgrades/templates/wcs-about.php:177 +#: includes/upgrades/templates/wcs-about-2-0.php:177 msgid "" "Subscriptions 2.0 introduces a new object for working with a subscription " "at the application level. The cumbersome APIs for retrieving or modifying a " "subscription's data are gone!" msgstr "" -#: includes/upgrades/templates/wcs-about.php:180 +#: includes/upgrades/templates/wcs-about-2-0.php:180 #. translators: all placeholders are opening and closing tags, no need #. to order them msgid "" @@ -2171,18 +3003,18 @@ msgid "" "%s$subscription->get_total()%s." msgstr "" -#: includes/upgrades/templates/wcs-about.php:184 +#: includes/upgrades/templates/wcs-about-2-0.php:184 msgid "REST API Endpoints" msgstr "" -#: includes/upgrades/templates/wcs-about.php:185 +#: includes/upgrades/templates/wcs-about-2-0.php:185 msgid "" "We didn't just improve interfaces for humans, we also improved them for " "computers. Your applications can now create, read, update or delete " "subscriptions via RESTful API endpoints." msgstr "" -#: includes/upgrades/templates/wcs-about.php:188 +#: includes/upgrades/templates/wcs-about-2-0.php:188 #. translators: all placeholders are opening and closing tags, no need #. to order them msgid "" @@ -2191,10 +3023,283 @@ msgid "" "subscription? Get %s/wc-api/v2/subscriptions//%s." msgstr "" -#: includes/upgrades/templates/wcs-about.php:194 +#: includes/upgrades/templates/wcs-about-2-0.php:194 msgid "Go to WooCommerce Subscriptions Settings" msgstr "" +#: includes/upgrades/templates/wcs-about.php:19 +msgid "Welcome to Subscriptions 2.1!" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:23 +msgid "" +"Version 2.1 introduces some great new features requested by store managers " +"just like you (and possibly even by %syou%s)." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:49 +msgid "Subscription Reports" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:50 +msgid "" +"How many customers stay subscribed for more than 6 months? What is the " +"average lifetime value of your subscribers? How much renewal revenue will " +"your store earn next month?" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:51 +msgid "These are important questions for any subscription commerce business." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:52 +msgid "" +"Prior to Subscriptions 2.1, they were not easy to answer. Subscriptions 2.1 " +"introduces new reports to answer these questions, and many more." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:54 +msgid "View Reports" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:67 +msgid "Automatic Failed Payment Retry" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:68 +msgid "" +"Failed recurring payments can now be retried automatically. This helps " +"recover revenue that would otherwise be lost due to payment methods being " +"declined only temporarily." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:69 +msgid "" +"By default, Subscriptions will retry the payment 5 times over 7 days. The " +"rules that control the retry system can be modified to customise:" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:71 +msgid "the total number of retry attempts" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:72 +msgid "how long to wait between retry attempts" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:73 +msgid "emails sent to the customer and store manager" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:74 +msgid "the status applied to the renewal order and subscription" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:76 +msgid "" +"The retry system is disabled by default. To enable it, visit the " +"Subscriptions settings administration screen." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:78 +msgid "Enable Automatic Retry" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:90 +msgid "New Subscription Emails" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:91 +msgid "Subscriptions 2.1 also introduces a number of new emails to notify you when:" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:93 +msgid "a customer suspends a subscription" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:94 +msgid "an automatic payment fails" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:95 +msgid "a subscription expires" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:97 +msgid "" +"These emails can be enabled, disabled and customised under the " +"%sWooCommerce > Settings > Emails%s administration screen." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:99 +msgid "View Email Settings" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:108 +msgid "But wait, there's more!" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:109 +msgid "" +"That's not all we've working on for the last 12 months when it comes to " +"Subscriptions. We've also released free mini-extensions to help you get the " +"most from your subscription store." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:115 +msgid "Subscription Gifting" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:116 +msgid "" +"What happens when a customer wants to purchase a subscription product for " +"someone else?" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:117 +msgid "" +"The free Gifting extension makes it possible for one person to purchase a " +"subscription product for someone else. It then shares control of the " +"subscription between the purchaser and recipient, allowing both to manage " +"the subscription over its lifecycle." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:127 +msgid "" +"Import subscriptions to WooCommerce via CSV, or export your subscriptions " +"from WooCommerce to a CSV with the WooCommerce Subscriptions " +"Importer/Exporter extension." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:128 +msgid "" +"This free extension makes it possible to migrate subscribers from 3rd party " +"systems to WooCommerce. It also makes it possible to export your " +"subscription data for analysis in spreadsheet tools or 3rd party apps." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:137 +msgid "Subscribe All the Things" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:138 +msgid "Want your customers to be able to subscribe to non-subscription products?" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:139 +msgid "" +"With WooCommerce Subscribe All the Things, they can! This experimental " +"extension is exploring how to convert any product, including Product " +"Bundles and Composite Products, into a subscription product. It also offers " +"customers a way to subscribe to a cart of non-subscription products." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:157 +#. translators: placeholders are opening and closing tags +msgid "Customise Retry Rules" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:159 +msgid "" +"The best part about the new automatic retry system is that the retry rules " +"are completely customisable." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:162 +#. translators: all placeholders are opening and closing tags, no need +#. to order them +msgid "" +"With the %s'wcs_default_retry_rules'%s filter, you can define a set of " +"default rules to apply to all failed payments in your store." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:166 +#. translators: all placeholders are opening and closing tags, no need +#. to order them +msgid "" +"To apply a specific rule based on certain conditions, like high value " +"orders or an infrequent renewal schedule, you can use the retry specific " +"%s'wcs_get_retry_rule'%s filter. This provides the ID of the renewal order " +"for the failed payment, which can be used to find information about the " +"products, subscription and totals to which the failed payment relates." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:174 +msgid "WP REST API Endpoints" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:177 +#. translators: $1: opening tag linking to WC API docs, $2: closing +#. tag, $3: opening tag linking to WP API docs, $4: closing tag +msgid "" +"WooCommerce 2.6 added support for %1$sREST API%2$s endpoints built on " +"WordPress core's %3$sREST API%4$s infrastructure." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:179 +msgid "Subscriptions 2.1 adds support for subscription data to this infrastructure." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:180 +msgid "" +"Your applications can now create, read, update or delete subscriptions via " +"RESTful API endpoints with the same design as the latest version of " +"WooCommerce's REST API endpoints." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:183 +#. translators: all placeholders are opening and closing tags, no need +#. to order them +msgid "" +"Want to list all the subscriptions on a site? Get " +"%s/wp-json/wc/v1/subscriptions%s." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:187 +#. translators: all placeholders are opening and closing tags, no need +#. to order them +msgid "" +"Want the details of a specific subscription? Get " +"%s/wp-json/wc/v1/subscriptions//%s." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:197 +#. translators: placeholders are opening and closing code tags +msgid "Honour Renewal Order Data" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:199 +msgid "" +"In previous versions of Subscriptions, the subscription total was passed to " +"payment gateways as the amount to charge for automatic renewal payments. " +"This made it unnecessarily complicated to add one-time fees or discounts to " +"a renewal." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:202 +#. translators: placeholders are opening and closing tags +msgid "" +"Subscriptions 2.1 now passes the renewal order's total, making it possible " +"to add a fee or discount to the renewal order with simple one-liners like " +"%s$order->add_fee()%s or %s$order->add_coupon()%s." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:206 +#. translators: placeholders are opening and closing tags +msgid "" +"Subscriptions also now uses the renewal order to setup the cart for " +"%smanual renewals%s, making it easier to add products or discounts to a " +"single renewal paid manually." +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:212 +msgid "See the full guide to What's New in Subscriptions version 2.1 »" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:213 +msgid "Go to WooCommerce Subscriptions Settings »" +msgstr "" + #: includes/upgrades/templates/wcs-upgrade-in-progress.php:24 msgid "WooCommerce Subscriptions Update in Progress" msgstr "" @@ -2313,21 +3418,21 @@ msgstr "" msgid "There was an error with the update. Please refresh the page and try again." msgstr "" -#: includes/wcs-cart-functions.php:73 +#: includes/wcs-cart-functions.php:75 msgid "Shipping via %s" msgstr "" -#: includes/wcs-cart-functions.php:91 +#: includes/wcs-cart-functions.php:95 msgid "Shipping" msgid_plural "Shipping %d" msgstr[0] "" msgstr[1] "" -#: includes/wcs-cart-functions.php:220 +#: includes/wcs-cart-functions.php:224 msgid "Free shipping coupon" msgstr "" -#: includes/wcs-cart-functions.php:323 +#: includes/wcs-cart-functions.php:327 #. translators: placeholder is a date msgid "First renewal: %s" msgstr "" @@ -2437,27 +3542,27 @@ msgstr "" msgid "MM" msgstr "" -#: includes/wcs-order-functions.php:267 +#: includes/wcs-order-functions.php:298 msgid "Subscription Renewal Order – %s" msgstr "" -#: includes/wcs-order-functions.php:270 +#: includes/wcs-order-functions.php:301 msgid "Resubscribe Order – %s" msgstr "" -#: includes/wcs-order-functions.php:289 +#: includes/wcs-order-functions.php:320 msgid "$type passed to the function was not a string." msgstr "" -#: includes/wcs-order-functions.php:294 +#: includes/wcs-order-functions.php:325 msgid "\"%s\" is not a valid new order type." msgstr "" -#: includes/wcs-order-functions.php:396 +#: includes/wcs-order-functions.php:512 msgid "Invalid data. No valid subscription / order was passed in." msgstr "" -#: includes/wcs-order-functions.php:400 +#: includes/wcs-order-functions.php:516 msgid "Invalid data. No valid item id was passed in." msgstr "" @@ -2486,56 +3591,71 @@ msgstr[0] "" msgstr[1] "" #: includes/wcs-user-functions.php:279 -#: templates/single-product/add-to-cart/subscription.php:42 -#: templates/single-product/add-to-cart/variable-subscription.php:30 +#: templates/single-product/add-to-cart/subscription.php:41 +#: templates/single-product/add-to-cart/variable-subscription.php:29 msgid "Resubscribe" msgstr "" -#: templates/admin/html-variation-price.php:20 -msgid "Sign-up Fee: (%s)" +#: templates/admin/deprecated/html-variation-price.php:20 +#: templates/admin/deprecated/html-variation-price.php:30 +#. translators: placeholder is a currency symbol / code +msgid "Subscription Price (%s)" msgstr "" -#: templates/admin/html-variation-price.php:25 -msgid "Free Trial:" +#: templates/admin/deprecated/html-variation-price.php:46 +msgid "Subscription Periods" msgstr "" -#: templates/admin/html-variation-price.php:32 -msgid "Subscription Trial Period:" +#: templates/admin/deprecated/html-variation-price.php:69 +msgid "Subscription Length" msgstr "" -#: templates/admin/html-variation-price.php:50 -msgid "Billing Interval:" +#: templates/admin/deprecated/html-variation-price.php:85 +msgid "Sign-up Fee (%s)" msgstr "" -#: templates/admin/html-variation-price.php:57 -msgid "Billing Period:" +#: templates/admin/deprecated/html-variation-price.php:97 +#: templates/admin/deprecated/html-variation-price.php:104 +msgid "Free Trial" msgstr "" -#: templates/admin/html-variation-price.php:66 -msgid "Subscription Length:" +#: templates/admin/deprecated/html-variation-synchronisation.php:30 +msgid "Synchronise Renewals" msgstr "" -#: templates/admin/post-types/writepanels/order-shipping-html.php:8 +#: templates/admin/deprecated/order-shipping-html.php:8 msgid "Label" msgstr "" -#: templates/admin/post-types/writepanels/order-shipping-html.php:13 +#: templates/admin/deprecated/order-shipping-html.php:13 msgid "Shipping Method" msgstr "" -#: templates/admin/post-types/writepanels/order-shipping-html.php:34 -#: templates/admin/post-types/writepanels/order-shipping-html.php:36 +#: templates/admin/deprecated/order-shipping-html.php:34 +#: templates/admin/deprecated/order-shipping-html.php:36 msgid "Other" msgstr "" -#: templates/admin/post-types/writepanels/order-tax-html.php:17 +#: templates/admin/deprecated/order-tax-html.php:17 msgid "Recurring Sales Tax:" msgstr "" -#: templates/admin/post-types/writepanels/order-tax-html.php:21 +#: templates/admin/deprecated/order-tax-html.php:21 msgid "Shipping Tax:" msgstr "" +#: templates/admin/html-variation-price.php:31 +msgid "Subscription trial period:" +msgstr "" + +#: templates/admin/html-variation-price.php:49 +msgid "Billing interval:" +msgstr "" + +#: templates/admin/html-variation-price.php:56 +msgid "Billing Period:" +msgstr "" + #: templates/cart/cart-recurring-shipping.php:19 msgid "Recurring shipping options can be selected on checkout." msgstr "" @@ -2569,55 +3689,32 @@ msgstr "" msgid "Recurring Total" msgstr "" -#: templates/emails/admin-new-renewal-order.php:65 -#: templates/emails/customer-processing-renewal-order.php:65 -#: templates/emails/plain/admin-new-renewal-order.php:50 -#: templates/myaccount/view-subscription.php:243 -msgid "Customer details" -msgstr "" - -#: templates/emails/admin-new-renewal-order.php:71 -#: templates/emails/customer-processing-renewal-order.php:71 -#. translators: $1: opening tag, $2: closing tag, $3: billing -#. email -msgid "%1$sEmail:%2$s %3$s" -msgstr "" - -#: templates/emails/admin-new-renewal-order.php:79 -#: templates/emails/customer-processing-renewal-order.php:79 -#. translators: $1: opening tag, $2: closing tag, $3: billing -#. phone -msgid "%1$sTel:%2$s %3$s" -msgstr "" - #: templates/emails/admin-new-switch-order.php:24 msgid "Switch Order Details" msgstr "" -#: templates/emails/admin-new-switch-order.php:29 -#: templates/emails/customer-completed-switch-order.php:30 -#: templates/emails/customer-renewal-invoice.php:35 -#. translators: placeholder is the order's number -msgid "Order: %s" -msgstr "" - -#: templates/emails/admin-new-switch-order.php:67 -#: templates/emails/customer-completed-switch-order.php:66 +#: templates/emails/admin-new-switch-order.php:30 +#: templates/emails/customer-completed-switch-order.php:28 msgid "New Subscription Details" msgstr "" -#: templates/emails/admin-new-switch-order.php:71 -#: templates/emails/customer-completed-switch-order.php:70 -msgid "Subscription %s" +#: templates/emails/admin-payment-retry.php:28 +#: templates/emails/plain/admin-payment-retry.php:21 +msgid "The renewal order is as follows:" msgstr "" #: templates/emails/cancelled-subscription.php:19 #: templates/emails/plain/cancelled-subscription.php:16 -#. translators: $1: customer's billing first name, $2: customer's billing last -#. name +#. translators: $1: customer's billing first name and last name msgid "" -"A subscription belonging to %1$s %2$s has been cancelled. Their " -"subscription's details are as follows:" +"A subscription belonging to %1$s has been cancelled. Their subscription's " +"details are as follows:" +msgstr "" + +#: templates/emails/cancelled-subscription.php:46 +#: templates/emails/expired-subscription.php:46 +#: templates/emails/on-hold-subscription.php:46 +msgid "-" msgstr "" #: templates/emails/customer-completed-renewal-order.php:20 @@ -2636,10 +3733,6 @@ msgid "" "new order and subscription details are shown below for your reference:" msgstr "" -#: templates/emails/customer-completed-switch-order.php:26 -msgid "Order Details" -msgstr "" - #: templates/emails/customer-processing-renewal-order.php:17 #: templates/emails/plain/customer-processing-renewal-order.php:15 msgid "" @@ -2652,53 +3745,62 @@ msgstr "" msgid "Pay Now »" msgstr "" -#: templates/emails/plain/admin-new-renewal-order.php:24 -#: templates/emails/plain/admin-new-switch-order.php:24 -#: templates/emails/plain/customer-completed-renewal-order.php:22 -#: templates/emails/plain/customer-completed-switch-order.php:22 -#: templates/emails/plain/customer-processing-renewal-order.php:21 -#: templates/emails/plain/customer-renewal-invoice.php:27 -msgid "Order number: %s" +#: templates/emails/expired-subscription.php:19 +#: templates/emails/plain/expired-subscription.php:16 +#. translators: $1: customer's billing first name and last name +msgid "" +"A subscription belonging to %1$s has expired. Their subscription's details " +"are as follows:" msgstr "" -#: templates/emails/plain/admin-new-renewal-order.php:25 -#: templates/emails/plain/customer-completed-renewal-order.php:23 -#: templates/emails/plain/customer-completed-switch-order.php:23 -#: templates/emails/plain/customer-processing-renewal-order.php:22 -#: templates/emails/plain/customer-renewal-invoice.php:28 -msgid "Order date: %s" +#: templates/emails/on-hold-subscription.php:19 +#: templates/emails/plain/on-hold-subscription.php:16 +#. translators: $1: customer's billing first name and last name +msgid "" +"A subscription belonging to %1$s has been suspended by the user. Their " +"subscription's details are as follows:" msgstr "" -#: templates/emails/plain/admin-new-switch-order.php:47 -#. translators: placeholder is edit post link for the order -msgid "View order: %s" -msgstr "" - -#: templates/emails/plain/cancelled-subscription.php:22 +#: templates/emails/plain/cancelled-subscription.php:32 +#: templates/emails/plain/expired-subscription.php:32 +#: templates/emails/plain/on-hold-subscription.php:32 #. translators: placeholder is last time subscription was paid msgid "Last Payment: %s" msgstr "" -#: templates/emails/plain/cancelled-subscription.php:28 +#: templates/emails/plain/cancelled-subscription.php:39 #. translators: placeholder is localised date string msgid "End of Prepaid Term: %s" msgstr "" -#: templates/emails/plain/customer-completed-renewal-order.php:48 -#: templates/emails/plain/customer-processing-renewal-order.php:47 -msgid "Your details" -msgstr "" - -#: templates/emails/plain/customer-completed-switch-order.php:45 +#: templates/emails/plain/customer-completed-switch-order.php:23 #. translators: placeholder is order's view url msgid "View your order: %s" msgstr "" -#: templates/emails/plain/customer-completed-switch-order.php:70 +#: templates/emails/plain/customer-completed-switch-order.php:34 #. translators: placeholder is subscription's view url msgid "View your subscription: %s" msgstr "" +#: templates/emails/plain/email-order-details.php:16 +msgid "Order number: %s" +msgstr "" + +#: templates/emails/plain/email-order-details.php:17 +msgid "Order date: %s" +msgstr "" + +#: templates/emails/plain/expired-subscription.php:39 +#. translators: placeholder is localised date string +msgid "End Date: %s" +msgstr "" + +#: templates/emails/plain/on-hold-subscription.php:36 +#. translators: placeholder is localised date string +msgid "Date Suspended: %s" +msgstr "" + #: templates/emails/plain/subscription-info.php:16 #: templates/emails/subscription-info.php:14 msgid "Subscription Information:" @@ -2753,24 +3855,12 @@ msgstr "" msgid "Subscription Totals" msgstr "" -#: templates/myaccount/view-subscription.php:110 +#: templates/myaccount/view-subscription.php:109 msgid "Are you sure you want remove this item from your subscription?" msgstr "" -#: templates/myaccount/view-subscription.php:224 -msgid "Refunded:" -msgstr "" - -#: templates/myaccount/view-subscription.php:271 wcs-functions.php:254 -msgid "Billing Address" -msgstr "" - -#: templates/myaccount/view-subscription.php:290 wcs-functions.php:253 -msgid "Shipping Address" -msgstr "" - -#: templates/single-product/add-to-cart/subscription.php:45 -#: templates/single-product/add-to-cart/variable-subscription.php:33 +#: templates/single-product/add-to-cart/subscription.php:43 +#: templates/single-product/add-to-cart/variable-subscription.php:31 msgid "You have an active subscription to this product already." msgstr "" @@ -2778,91 +3868,99 @@ msgstr "" msgid "This product is currently out of stock and unavailable." msgstr "" -#: templates/single-product/add-to-cart/variable-subscription.php:45 +#: templates/single-product/add-to-cart/variable-subscription.php:43 msgid "Clear selection" msgstr "" -#: wcs-functions.php:226 +#: wcs-functions.php:228 msgid "Can not get status name. Status is not a string." msgstr "" -#: wcs-functions.php:249 +#: wcs-functions.php:251 msgid "Can not get address type display name. Address type is not a string." msgstr "" -#: wcs-functions.php:290 +#: wcs-functions.php:255 +msgid "Shipping Address" +msgstr "" + +#: wcs-functions.php:256 +msgid "Billing Address" +msgstr "" + +#: wcs-functions.php:314 msgid "Date type is not a string." msgstr "" -#: wcs-functions.php:292 +#: wcs-functions.php:316 msgid "Date type can not be an empty string." msgstr "" -#: woocommerce-subscriptions.php:215 +#: woocommerce-subscriptions.php:220 msgid "This is where subscriptions are stored." msgstr "" -#: woocommerce-subscriptions.php:259 +#: woocommerce-subscriptions.php:264 msgid "No Subscriptions found" msgstr "" -#: woocommerce-subscriptions.php:261 +#: woocommerce-subscriptions.php:266 msgid "" "Subscriptions will appear here for you to view and manage once purchased by " "a customer." msgstr "" -#: woocommerce-subscriptions.php:263 +#: woocommerce-subscriptions.php:268 #. translators: placeholders are opening and closing link tags msgid "%sLearn more about managing subscriptions »%s" msgstr "" -#: woocommerce-subscriptions.php:265 +#: woocommerce-subscriptions.php:270 #. translators: placeholders are opening and closing link tags msgid "%sAdd a subscription product »%s" msgstr "" -#: woocommerce-subscriptions.php:379 +#: woocommerce-subscriptions.php:384 msgid "" "A subscription renewal has been removed from your cart. Multiple " "subscriptions can not be purchased at the same time." msgstr "" -#: woocommerce-subscriptions.php:385 +#: woocommerce-subscriptions.php:390 msgid "" "A subscription has been removed from your cart. Due to payment gateway " "restrictions, different subscription products can not be purchased at the " "same time." msgstr "" -#: woocommerce-subscriptions.php:391 +#: woocommerce-subscriptions.php:396 msgid "" "A subscription has been removed from your cart. Products and subscriptions " "can not be purchased at the same time." msgstr "" -#: woocommerce-subscriptions.php:525 woocommerce-subscriptions.php:542 +#: woocommerce-subscriptions.php:530 woocommerce-subscriptions.php:547 #. translators: placeholder is a number, this is for the teens #. translators: placeholder is a number, numbers ending in 4-9, 0 msgid "%sth" msgstr "" -#: woocommerce-subscriptions.php:530 +#: woocommerce-subscriptions.php:535 #. translators: placeholder is a number, numbers ending in 1 msgid "%sst" msgstr "" -#: woocommerce-subscriptions.php:534 +#: woocommerce-subscriptions.php:539 #. translators: placeholder is a number, numbers ending in 2 msgid "%snd" msgstr "" -#: woocommerce-subscriptions.php:538 +#: woocommerce-subscriptions.php:543 #. translators: placeholder is a number, numbers ending in 3 msgid "%srd" msgstr "" -#: woocommerce-subscriptions.php:568 +#: woocommerce-subscriptions.php:573 #. translators: 1$-2$: opening and closing tags, 3$-4$: link tags, #. takes to woocommerce plugin on wp.org, 5$-6$: opening and closing link tags, #. leads to plugins.php in admin @@ -2872,26 +3970,20 @@ msgid "" "%5$sinstall & activate WooCommerce »%6$s" msgstr "" -#: woocommerce-subscriptions.php:575 +#: woocommerce-subscriptions.php:580 #. translators: 1$-2$: opening and closing tags, 3$-4$: opening and #. closing link tags, leads to plugin admin msgid "" "%1$sWooCommerce Subscriptions is inactive.%2$s This version of " -"Subscriptions requires WooCommerce 2.3 or newer. Please %3$supdate " -"WooCommerce to version 2.3 or newer »%4$s" +"Subscriptions requires WooCommerce 2.4 or newer. Please %3$supdate " +"WooCommerce to version 2.4 or newer »%4$s" msgstr "" -#: woocommerce-subscriptions.php:746 -#. translators: 1$-2$: opening and closing tags, 3$-4$: opening and -#. closing link tags, leads to plugin admin -msgid "" -"%1$sYou have an out-of-date version of WooCommerce installed%2$s. " -"WooCommerce Subscriptions no longer supports versions of WooCommerce prior " -"to 2.3. Please %3$supgrade WooCommerce to version 2.3 or newer%4$s to avoid " -"issues." +#: woocommerce-subscriptions.php:606 +msgid "Variable Subscription" msgstr "" -#: woocommerce-subscriptions.php:781 +#: woocommerce-subscriptions.php:765 #. translators: 1$-2$: opening and closing tags, 3$-4$: opening and #. closing link tags. Leads to duplicate site article on docs msgid "" @@ -2901,19 +3993,19 @@ msgid "" "environment. %3$sLearn more »%4$s." msgstr "" -#: woocommerce-subscriptions.php:783 +#: woocommerce-subscriptions.php:767 msgid "Quit nagging me (but don't enable automatic payments)" msgstr "" -#: woocommerce-subscriptions.php:784 +#: woocommerce-subscriptions.php:768 msgid "Enable automatic payments" msgstr "" -#: woocommerce-subscriptions.php:962 +#: woocommerce-subscriptions.php:946 msgid "Support" msgstr "" -#: woocommerce-subscriptions.php:1063 +#: woocommerce-subscriptions.php:1047 #. translators: placeholders are opening and closing tags. Leads to docs on #. version 2 msgid "" @@ -2924,14 +4016,14 @@ msgid "" "2.0 »%s" msgstr "" -#: woocommerce-subscriptions.php:1078 +#: woocommerce-subscriptions.php:1062 msgid "" "Warning! You are running version %s of WooCommerce Subscriptions plugin " "code but your database has been upgraded to Subscriptions version 2.0. This " "will cause major problems on your store." msgstr "" -#: woocommerce-subscriptions.php:1079 +#: woocommerce-subscriptions.php:1063 msgid "" "Please upgrade the WooCommerce Subscriptions plugin to version 2.0 or newer " "immediately. If you need assistance, after upgrading to Subscriptions v2.0, " @@ -2943,7 +4035,7 @@ msgid "WooCommerce Subscriptions" msgstr "" #. Plugin URI of the plugin/theme -msgid "http://www.woothemes.com/products/woocommerce-subscriptions/" +msgid "http://www.woocommerce.com/products/woocommerce-subscriptions/" msgstr "" #. Description of the plugin/theme @@ -2960,34 +4052,31 @@ msgstr "" msgid "http://prospress.com/" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:152 -#: includes/admin/class-wc-subscriptions-admin.php:195 -#: templates/admin/deprecated/html-variation-price.php:31 -#: templates/admin/deprecated/html-variation-price.php:86 -#: templates/admin/html-variation-price.php:21 -#: templates/admin/html-variation-price.php:48 -msgctxt "example price" -msgid "e.g. 9.90" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:175 -msgctxt "for in \"Every month _for_ 12 months\"" -msgid "for" -msgstr "" - -#: includes/admin/class-wc-subscriptions-admin.php:219 -#: templates/admin/deprecated/html-variation-price.php:118 -#: templates/admin/html-variation-price.php:27 +#: includes/admin/class-wc-subscriptions-admin.php:145 #. translators: placeholder is trial period validation message if passed an #. invalid value (e.g. "Trial period can not exceed 4 weeks") -msgctxt "Trial period dropdown's description in pricing fields" +msgctxt "Trial period field tooltip on Edit Product administration screen" msgid "" "An optional period of time to wait before charging the first recurring " "payment. Any sign up fee will still be charged at the outset of the " "subscription. %s" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:751 +#: includes/admin/class-wc-subscriptions-admin.php:158 +msgctxt "example price" +msgid "e.g. 5.90" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:192 +#: templates/admin/deprecated/html-variation-price.php:31 +#: templates/admin/deprecated/html-variation-price.php:86 +#: templates/admin/html-variation-price.php:21 +#: templates/admin/html-variation-price.php:47 +msgctxt "example price" +msgid "e.g. 9.90" +msgstr "" + +#: includes/admin/class-wc-subscriptions-admin.php:725 #. translators: placeholders are for HTML tags. They are 1$: "

", 2$: #. "

", 3$: "

", 4$: "", 5$: "", 6$: "", 7$: "", 8$: #. "

" @@ -2998,7 +4087,7 @@ msgid "" "%6$sVariable subscription%7$s.%8$s" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:753 +#: includes/admin/class-wc-subscriptions-admin.php:727 #. translators: placeholders are for HTML tags. They are 1$: "

", 2$: #. "

", 3$: "

", 4$: "

" msgctxt "used in admin pointer script params in javascript as price pointer content" @@ -3008,74 +4097,74 @@ msgid "" "sign-up fee and free trial.%4$s" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1083 +#: includes/admin/class-wc-subscriptions-admin.php:1038 msgctxt "option section heading" msgid "Renewals" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1115 +#: includes/admin/class-wc-subscriptions-admin.php:1070 msgctxt "options section heading" msgid "Miscellaneous" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1123 +#: includes/admin/class-wc-subscriptions-admin.php:1078 msgctxt "there's a number immediately in front of this text" msgid "suspensions per billing period." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1390 +#: includes/admin/class-wc-subscriptions-admin.php:1323 msgctxt "in [subscriptions] shortcode" msgid "No subscriptions found." msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1399 +#: includes/admin/class-wc-subscriptions-admin.php:1332 #. translators: order number msgctxt "in [subscriptions] shortcode" msgid "Subscription %s" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1419 +#: includes/admin/class-wc-subscriptions-admin.php:1352 msgctxt "label that indicates whether debugging is turned on for the plugin" msgid "WCS_DEBUG" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1425 +#: includes/admin/class-wc-subscriptions-admin.php:1358 msgctxt "Live or Staging, Label on WooCommerce -> System Status page" msgid "Subscriptions Mode" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1426 +#: includes/admin/class-wc-subscriptions-admin.php:1359 msgctxt "refers to staging site" msgid "Staging" msgstr "" -#: includes/admin/class-wc-subscriptions-admin.php:1426 +#: includes/admin/class-wc-subscriptions-admin.php:1359 msgctxt "refers to live site" msgid "Live" msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:54 +#: includes/admin/class-wcs-admin-meta-boxes.php:56 msgctxt "meta box title" msgid "Subscription Data" msgstr "" -#: includes/admin/class-wcs-admin-meta-boxes.php:56 +#: includes/admin/class-wcs-admin-meta-boxes.php:58 msgctxt "meta box title" msgid "Billing Schedule" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:154 +#: includes/admin/class-wcs-admin-post-types.php:233 msgctxt "an action on a subscription" msgid "Activate" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:155 +#: includes/admin/class-wcs-admin-post-types.php:234 msgctxt "an action on a subscription" msgid "Put on-hold" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:156 -#: includes/admin/class-wcs-admin-post-types.php:367 +#: includes/admin/class-wcs-admin-post-types.php:235 +#: includes/admin/class-wcs-admin-post-types.php:448 #: includes/class-wc-subscriptions-manager.php:1762 #: includes/wcs-user-functions.php:288 #: templates/myaccount/related-orders.php:66 @@ -3083,35 +4172,35 @@ msgctxt "an action on a subscription" msgid "Cancel" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:231 +#: includes/admin/class-wcs-admin-post-types.php:310 msgctxt "Used in order note. Reason why status changed." msgid "Subscription status changed by bulk edit:" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:325 +#: includes/admin/class-wcs-admin-post-types.php:406 msgctxt "number of orders linked to a subscription" msgid "Orders" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:421 +#: includes/admin/class-wcs-admin-post-types.php:502 msgctxt "meaning billing address" msgid "Billing:" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:459 +#: includes/admin/class-wcs-admin-post-types.php:540 #. translators: $1: is opening link, $2: is subscription order number, $3: is #. closing link tag, $4: is user's name msgctxt "Subscription title on admin table. (e.g.: #211 for John Doe)" msgid "%1$s#%2$s%3$s for %4$s" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:834 +#: includes/admin/class-wcs-admin-post-types.php:924 #. translators: placeholder is previous post title msgctxt "used in post updated messages" msgid "Subscription restored to revision from %s" msgstr "" -#: includes/admin/class-wcs-admin-post-types.php:839 +#: includes/admin/class-wcs-admin-post-types.php:929 msgctxt "used in \"Subscription scheduled for \"" msgid "M j, Y @ G:i" msgstr "" @@ -3142,6 +4231,14 @@ msgctxt "edit subscription header" msgid "Subscription #%s details" msgstr "" +#: includes/admin/meta-boxes/class-wcs-meta-box-subscription-data.php:126 +#: includes/class-wcs-change-payment-method-admin.php:52 +msgctxt "" +"The gateway ID displayed on the Edit Subscriptions screen when editing " +"payment method." +msgid "Gateway ID: [%s]" +msgstr "" + #: includes/admin/meta-boxes/views/html-related-orders-row.php:15 #: includes/class-wc-subscriptions-renewal-order.php:137 #: templates/myaccount/my-subscriptions.php:37 @@ -3151,12 +4248,13 @@ msgctxt "hash before order number" msgid "#%s" msgstr "" -#: includes/class-wcs-query.php:87 +#: includes/class-wcs-query.php:90 msgctxt "hash before order number" msgid "Subscription #%s" msgstr "" -#: includes/admin/meta-boxes/views/html-related-orders-row.php:29 +#: includes/admin/meta-boxes/views/html-related-orders-row.php:26 +#: includes/admin/meta-boxes/views/html-retries-table.php:44 #. translators: php date format msgctxt "post date" msgid "Y/m/d g:i:s A" @@ -3171,19 +4269,26 @@ msgctxt "table heading" msgid "Total" msgstr "" -#: templates/emails/cancelled-subscription.php:28 wcs-functions.php:275 +#: includes/class-wcs-retry-manager.php:95 +msgctxt "table heading" +msgid "Renewal Payment Retry" +msgstr "" + +#: templates/emails/cancelled-subscription.php:28 +#: templates/emails/expired-subscription.php:28 +#: templates/emails/on-hold-subscription.php:28 wcs-functions.php:277 msgctxt "table heading" msgid "Last Payment" msgstr "" #: templates/emails/subscription-info.php:19 -#: templates/myaccount/view-subscription.php:36 wcs-functions.php:272 +#: templates/myaccount/view-subscription.php:36 wcs-functions.php:274 msgctxt "table heading" msgid "Start Date" msgstr "" #: templates/emails/subscription-info.php:20 -#: templates/myaccount/view-subscription.php:42 wcs-functions.php:276 +#: templates/myaccount/view-subscription.php:42 wcs-functions.php:279 msgctxt "table heading" msgid "End Date" msgstr "" @@ -3196,33 +4301,53 @@ msgstr "" #: templates/myaccount/my-subscriptions.php:27 #: templates/myaccount/my-subscriptions.php:43 #: templates/myaccount/related-subscriptions.php:22 -#: templates/myaccount/related-subscriptions.php:38 wcs-functions.php:274 +#: templates/myaccount/related-subscriptions.php:38 wcs-functions.php:276 msgctxt "table heading" msgid "Next Payment" msgstr "" -#: wcs-functions.php:273 +#: wcs-functions.php:275 msgctxt "table heading" msgid "Trial End" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:267 +#: wcs-functions.php:278 +msgctxt "table heading" +msgid "Cancelled Date" +msgstr "" + +#: includes/admin/reports/class-wcs-report-retention-rate.php:156 +msgctxt "X axis label on retention rate graph" +msgid "Number of days after sign-up" +msgstr "" + +#: includes/admin/reports/class-wcs-report-retention-rate.php:159 +msgctxt "X axis label on retention rate graph" +msgid "Number of weeks after sign-up" +msgstr "" + +#: includes/admin/reports/class-wcs-report-retention-rate.php:162 +msgctxt "X axis label on retention rate graph" +msgid "Number of months after sign-up" +msgstr "" + +#: includes/api/legacy/class-wc-api-subscriptions.php:267 #. translators: placeholder is error message msgctxt "API error message when editing the order failed" msgid "Edit subscription failed with error: %s" msgstr "" -#: includes/api/class-wc-api-subscriptions.php:605 +#: includes/api/legacy/class-wc-api-subscriptions.php:605 msgctxt "API response confirming order note deleted from a subscription" msgid "Permanently deleted subscription note" msgstr "" -#: includes/class-wc-subscription.php:696 +#: includes/class-wc-subscription.php:715 msgctxt "original denotes there is no date to display" msgid "-" msgstr "" -#: includes/class-wc-subscription.php:752 +#: includes/class-wc-subscription.php:771 #. translators: placeholder is date type (e.g. "end", "next_payment"...) msgctxt "appears in an error message if date is wrong format" msgid "Invalid %s date. The date must be of the format: \"Y-m-d H:i:s\"." @@ -3252,22 +4377,27 @@ msgctxt "used in order note as reason for why subscription status changed" msgid "Subscription renewal payment due:" msgstr "" -#: includes/class-wc-subscriptions-manager.php:973 wcs-functions.php:205 +#: includes/class-wcs-retry-manager.php:250 +msgctxt "used in order note as reason for why subscription status changed" +msgid "Subscription renewal payment retry:" +msgstr "" + +#: includes/class-wc-subscriptions-manager.php:973 wcs-functions.php:207 msgctxt "Subscription status" msgid "Active" msgstr "" -#: includes/class-wc-subscriptions-manager.php:976 wcs-functions.php:207 +#: includes/class-wc-subscriptions-manager.php:976 wcs-functions.php:209 msgctxt "Subscription status" msgid "Cancelled" msgstr "" -#: includes/class-wc-subscriptions-manager.php:979 wcs-functions.php:209 +#: includes/class-wc-subscriptions-manager.php:979 wcs-functions.php:211 msgctxt "Subscription status" msgid "Expired" msgstr "" -#: includes/class-wc-subscriptions-manager.php:982 wcs-functions.php:204 +#: includes/class-wc-subscriptions-manager.php:982 wcs-functions.php:206 msgctxt "Subscription status" msgid "Pending" msgstr "" @@ -3282,17 +4412,17 @@ msgctxt "Subscription status" msgid "On-hold" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:2019 wcs-functions.php:208 +#: includes/class-wc-subscriptions-switcher.php:2253 wcs-functions.php:210 msgctxt "Subscription status" msgid "Switched" msgstr "" -#: wcs-functions.php:206 +#: wcs-functions.php:208 msgctxt "Subscription status" msgid "On hold" msgstr "" -#: wcs-functions.php:210 +#: wcs-functions.php:212 msgctxt "Subscription status" msgid "Pending Cancellation" msgstr "" @@ -3304,127 +4434,134 @@ msgctxt "used in a select box" msgid "%1$s-%2$s" msgstr "" -#: includes/class-wc-subscriptions-order.php:648 +#: includes/class-wc-subscriptions-order.php:688 msgctxt "An order type" msgid "Original" msgstr "" -#: includes/class-wc-subscriptions-order.php:651 +#: includes/class-wc-subscriptions-order.php:689 msgctxt "An order type" -msgid "Renewal" +msgid "Subscription Parent" msgstr "" -#: includes/class-wc-subscriptions-renewal-order.php:242 -#. translators: 1$: blog name, 2$: order number -msgctxt "used in new renewal order email, deprecated" -msgid "[%1$s] New Subscription Renewal Order (%2$s)" +#: includes/class-wc-subscriptions-order.php:690 +msgctxt "An order type" +msgid "Subscription Renewal" msgstr "" -#: includes/class-wc-subscriptions-renewal-order.php:264 -#: includes/class-wc-subscriptions-renewal-order.php:288 -#. translators: placeholder is blog name -msgctxt "used as email subject for renewal order notification email to customer" -msgid "[%s] Subscription Renewal Order" +#: includes/class-wc-subscriptions-order.php:691 +msgctxt "An order type" +msgid "Subscription Resubscribe" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:334 -#: includes/class-wc-subscriptions-switcher.php:351 -#: includes/class-wc-subscriptions-switcher.php:385 +#: includes/class-wc-subscriptions-order.php:692 +msgctxt "An order type" +msgid "Subscription Switch" +msgstr "" + +#: includes/class-wc-subscriptions-order.php:693 +msgctxt "An order type" +msgid "Non-subscription" +msgstr "" + +#: includes/class-wc-subscriptions-switcher.php:324 +#: includes/class-wc-subscriptions-switcher.php:341 +#: includes/class-wc-subscriptions-switcher.php:375 #: includes/class-wc-subscriptions-synchroniser.php:172 msgctxt "when to allow a setting" msgid "Never" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:335 +#: includes/class-wc-subscriptions-switcher.php:325 msgctxt "when to allow switching" msgid "Between Subscription Variations" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:336 +#: includes/class-wc-subscriptions-switcher.php:326 msgctxt "when to allow switching" msgid "Between Grouped Subscriptions" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:337 +#: includes/class-wc-subscriptions-switcher.php:327 msgctxt "when to allow switching" msgid "Between Both Variations & Grouped Subscriptions" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:352 +#: includes/class-wc-subscriptions-switcher.php:342 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades of Virtual Subscription Products Only" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:353 +#: includes/class-wc-subscriptions-switcher.php:343 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades of All Subscription Products" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:354 +#: includes/class-wc-subscriptions-switcher.php:344 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades & Downgrades of Virtual Subscription Products Only" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:355 +#: includes/class-wc-subscriptions-switcher.php:345 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades & Downgrades of All Subscription Products" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:369 +#: includes/class-wc-subscriptions-switcher.php:359 msgctxt "when to prorate signup fee when switching" msgid "Never (do not charge a sign up fee)" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:370 +#: includes/class-wc-subscriptions-switcher.php:360 msgctxt "when to prorate signup fee when switching" msgid "Never (charge the full sign up fee)" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:371 +#: includes/class-wc-subscriptions-switcher.php:361 msgctxt "when to prorate signup fee when switching" msgid "Always" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:386 +#: includes/class-wc-subscriptions-switcher.php:376 #: includes/class-wc-subscriptions-synchroniser.php:173 msgctxt "when to prorate first payment / subscription length" msgid "For Virtual Subscription Products Only" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:387 +#: includes/class-wc-subscriptions-switcher.php:377 #: includes/class-wc-subscriptions-synchroniser.php:174 msgctxt "when to prorate first payment / subscription length" msgid "For All Subscription Products" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:715 -#. translators: 1$: old item name, 2$: new item name when switching -msgctxt "used in order notes" -msgid "Customer switched from: %1$s to %2$s." -msgstr "" - -#: includes/class-wc-subscriptions-switcher.php:1624 +#: includes/class-wc-subscriptions-switcher.php:1688 msgctxt "a switch order" msgid "Downgrade" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:1627 +#: includes/class-wc-subscriptions-switcher.php:1691 msgctxt "a switch order" msgid "Upgrade" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:1630 +#: includes/class-wc-subscriptions-switcher.php:1694 msgctxt "a switch order" msgid "Crossgrade" msgstr "" -#: includes/class-wc-subscriptions-switcher.php:1635 +#: includes/class-wc-subscriptions-switcher.php:1699 #. translators: %1: product subtotal, %2: HTML span tag, %3: direction #. (upgrade, downgrade, crossgrade), %4: closing HTML span tag msgctxt "product subtotal string" msgid "%1$s %2$s(%3$s)%4$s" msgstr "" +#: includes/class-wc-subscriptions-switcher.php:1825 +#. translators: 1$: old item, 2$: new item when switching +msgctxt "used in order notes" +msgid "Customer switched from: %1$s to %2$s." +msgstr "" + #: includes/class-wc-subscriptions-synchroniser.php:50 #. translators: placeholder is a year (e.g. "2016") msgctxt "used in subscription product edit screen" @@ -3443,14 +4580,14 @@ msgid "" "For example, the first day of the month. %sLearn more%s." msgstr "" -#: includes/class-wc-subscriptions-synchroniser.php:236 +#: includes/class-wc-subscriptions-synchroniser.php:235 #: templates/admin/deprecated/html-variation-synchronisation.php:36 -#: templates/admin/html-variation-synchronisation.php:32 +#: templates/admin/html-variation-synchronisation.php:34 msgctxt "input field placeholder for day field for annual subscriptions" msgid "Day" msgstr "" -#: includes/class-wcs-cart-renewal.php:569 +#: includes/class-wcs-cart-renewal.php:642 msgctxt "" "Used in WooCommerce by removed item notification: \"_All linked " "subscription items were_ removed. Undo?\" Filter for item title." @@ -3481,6 +4618,11 @@ msgctxt "used in order note" msgid "IPN subscription payment %s." msgstr "" +#: includes/class-wcs-retry-manager.php:182 +msgctxt "used in order note as reason for why status changed" +msgid "Retry rule applied:" +msgstr "" + #: includes/class-wcs-user-change-status-handler.php:56 msgctxt "order note left on subscription after user action" msgid "Subscription reactivated by the subscriber from their account page." @@ -3518,45 +4660,61 @@ msgctxt "default email subject for cancelled emails sent to the admin" msgid "[%s] Subscription Cancelled" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:120 -#: includes/emails/class-wcs-email-customer-renewal-invoice.php:174 +#: includes/emails/class-wcs-email-cancelled-subscription.php:126 +#: includes/emails/class-wcs-email-customer-renewal-invoice.php:181 +#: includes/emails/class-wcs-email-expired-subscription.php:124 +#: includes/emails/class-wcs-email-on-hold-subscription.php:124 msgctxt "an email notification" msgid "Enable/Disable" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:126 +#: includes/emails/class-wcs-email-cancelled-subscription.php:132 +#: includes/emails/class-wcs-email-expired-subscription.php:130 +#: includes/emails/class-wcs-email-on-hold-subscription.php:130 msgctxt "of an email" msgid "Recipient(s)" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:134 +#: includes/emails/class-wcs-email-cancelled-subscription.php:140 +#: includes/emails/class-wcs-email-expired-subscription.php:138 +#: includes/emails/class-wcs-email-on-hold-subscription.php:138 msgctxt "of an email" msgid "Subject" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:141 +#: includes/emails/class-wcs-email-cancelled-subscription.php:147 +#: includes/emails/class-wcs-email-expired-subscription.php:145 +#: includes/emails/class-wcs-email-on-hold-subscription.php:145 msgctxt "" "Name the setting that controls the main heading contained within the email " "notification" msgid "Email Heading" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:148 +#: includes/emails/class-wcs-email-cancelled-subscription.php:154 +#: includes/emails/class-wcs-email-expired-subscription.php:152 +#: includes/emails/class-wcs-email-on-hold-subscription.php:152 msgctxt "text, html or multipart" msgid "Email type" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:154 +#: includes/emails/class-wcs-email-cancelled-subscription.php:160 +#: includes/emails/class-wcs-email-expired-subscription.php:158 +#: includes/emails/class-wcs-email-on-hold-subscription.php:158 msgctxt "email type" msgid "Plain text" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:155 +#: includes/emails/class-wcs-email-cancelled-subscription.php:161 +#: includes/emails/class-wcs-email-expired-subscription.php:159 +#: includes/emails/class-wcs-email-on-hold-subscription.php:159 msgctxt "email type" msgid "HTML" msgstr "" -#: includes/emails/class-wcs-email-cancelled-subscription.php:156 +#: includes/emails/class-wcs-email-cancelled-subscription.php:162 +#: includes/emails/class-wcs-email-expired-subscription.php:160 +#: includes/emails/class-wcs-email-on-hold-subscription.php:160 msgctxt "email type" msgid "Multipart" msgstr "" @@ -3587,7 +4745,21 @@ msgid "" "files" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:335 +#: includes/emails/class-wcs-email-expired-subscription.php:32 +#. translators: placeholder is {blogname}, a variable that will be substituted +#. when email is sent out +msgctxt "default email subject for expired emails sent to the admin" +msgid "[%s] Subscription Expired" +msgstr "" + +#: includes/emails/class-wcs-email-on-hold-subscription.php:32 +#. translators: placeholder is {blogname}, a variable that will be substituted +#. when email is sent out +msgctxt "default email subject for suspended emails sent to the admin" +msgid "[%s] Subscription Suspended" +msgstr "" + +#: includes/gateways/paypal/class-wcs-paypal.php:344 #: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php:208 #: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php:316 #: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php:327 @@ -3602,7 +4774,7 @@ msgctxt "" msgid "#" msgstr "" -#: includes/gateways/paypal/class-wcs-paypal.php:547 +#: includes/gateways/paypal/class-wcs-paypal.php:556 msgctxt "" "used in User Agent data sent to PayPal to help identify where a payment " "came from" @@ -3621,21 +4793,19 @@ msgctxt "data sent to paypal" msgid "%1$s subscription event triggered at %2$s" msgstr "" -#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:105 +#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:136 msgctxt "used in api error message if there is no severity code from PayPal" msgid "Error" msgstr "" -#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:107 +#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:138 msgctxt "used in api error message if there is no long message" msgid "Unknown error" msgstr "" -#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:119 -#: templates/admin/post-types/writepanels/order-shipping-html.php:14 -#: templates/admin/post-types/writepanels/order-tax-html.php:9 -#: templates/myaccount/view-subscription.php:276 -#: templates/myaccount/view-subscription.php:295 +#: includes/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php:150 +#: templates/admin/deprecated/order-shipping-html.php:14 +#: templates/admin/deprecated/order-tax-html.php:9 msgctxt "no information about something" msgid "N/A" msgstr "" @@ -3655,21 +4825,31 @@ msgctxt "item name sent to paypal" msgid "Subscription %1$s (Order %2$s) - %3$s" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:258 +#: includes/payment-retry/class-wcs-retry-post-store.php:33 +msgctxt "Post type name" +msgid "Renewal Payment Retries" +msgstr "" + +#: includes/payment-retry/class-wcs-retry-post-store.php:35 +msgctxt "Admin menu name" +msgid "Renewal Payment Retries" +msgstr "" + +#: includes/upgrades/class-wc-subscriptions-upgrader.php:287 #. translators: placeholder is number of upgraded subscriptions msgctxt "used in the subscriptions upgrader" msgid "Marked %s subscription products as \"sold individually\"." msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:289 -#: includes/upgrades/class-wc-subscriptions-upgrader.php:339 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:318 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:368 #. translators: placeholder is "{time_left}", will be replaced on front end #. with actual time msgctxt "Message that gets sent to front end." msgid "Estimated time left (minutes:seconds): %s" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:318 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:347 #. translators: placeholder is the number of subscriptions repaired msgctxt "Repair message that gets sent to front end." msgid "" @@ -3677,7 +4857,7 @@ msgid "" "customer notes." msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:324 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:353 #. translators: placeholder is number of subscriptions that were checked and #. did not need repairs. There's a space at the beginning! msgctxt "Repair message that gets sent to front end." @@ -3686,14 +4866,14 @@ msgid_plural "%d other subscriptions were checked and did not need any repairs." msgstr[0] "" msgstr[1] "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:328 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:357 #. translators: placeholder is "{execution_time}", which will be replaced on #. front end with actual time msgctxt "Repair message that gets sent to front end." msgid "(in %s seconds)" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:331 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:360 #. translators: $1: "Repaired x subs with incorrect dates...", $2: "X others #. were checked and no repair needed", $3: "(in X seconds)". Ordering for RTL #. languages. @@ -3701,7 +4881,7 @@ msgctxt "The assembled repair message that gets sent to front end." msgid "%1$s%2$s %3$s" msgstr "" -#: includes/upgrades/class-wc-subscriptions-upgrader.php:350 +#: includes/upgrades/class-wc-subscriptions-upgrader.php:379 #. translators: 1$: error message, 2$: opening link tag, 3$: closing link tag msgctxt "Error message that gets sent to front end when upgrading Subscriptions" msgid "" @@ -3709,30 +4889,53 @@ msgid "" "and try again. If problem persists, %2$scontact support%3$s." msgstr "" -#: includes/upgrades/templates/wcs-about.php:36 -#: woocommerce-subscriptions.php:961 +#: includes/upgrades/templates/wcs-about-2-0.php:36 +#: woocommerce-subscriptions.php:945 msgctxt "short for documents" msgid "Docs" msgstr "" -#: includes/upgrades/templates/wcs-about.php:121 +#: includes/upgrades/templates/wcs-about.php:35 +msgctxt "short for documents" +msgid "Documentation" +msgstr "" + +#: includes/upgrades/templates/wcs-about-2-0.php:121 msgctxt "h3 on the About Subscriptions page for this new feature" msgid "Change Payment Method" msgstr "" +#: includes/upgrades/templates/wcs-about.php:126 +msgctxt "h3 on the About Subscriptions page for this new feature" +msgid "Import/Export Subscriptions" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:55 +msgctxt "learn more link to subscription reports documentation" +msgid "Learn More" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:79 +msgctxt "learn more link to failed payment retry documentation" +msgid "Learn More" +msgstr "" + +#: includes/upgrades/templates/wcs-about.php:100 +msgctxt "learn more link to subscription emails documentation" +msgid "Learn More" +msgstr "" + #: includes/upgrades/templates/wcs-upgrade.php:45 msgctxt "text on submit button" msgid "Update Database" msgstr "" -#: includes/wcs-cart-functions.php:180 +#: includes/wcs-cart-functions.php:184 msgctxt "shipping method price" msgid "Free" msgstr "" -#: includes/wcs-cart-functions.php:255 -#: templates/myaccount/view-subscription.php:201 -#: templates/myaccount/view-subscription.php:206 +#: includes/wcs-cart-functions.php:259 #. translators: placeholder is price string, denotes tax included in cart/order #. total msgctxt "includes tax" @@ -3758,7 +4961,7 @@ msgctxt "" msgid "Invalid data. Type of copy is not a string." msgstr "" -#: includes/wcs-order-functions.php:263 wcs-functions.php:151 +#: includes/wcs-order-functions.php:294 wcs-functions.php:153 #. translators: Order date parsed by strftime msgctxt "Used in subscription post title. \"Subscription renewal order - \"" msgid "%b %d, %Y @ %I:%M %p" @@ -3801,8 +5004,8 @@ msgstr[0] "" msgstr[1] "" #: includes/wcs-time-functions.php:81 -msgctxt "Subscription length (eg \"$10 per month for _all time_\")" -msgid "all time" +msgctxt "Subscription length" +msgid "Never expire" msgstr "" #: includes/wcs-time-functions.php:86 @@ -3890,31 +5093,34 @@ msgctxt "example number of days / weeks / months" msgid "e.g. 3" msgstr "" +#: templates/admin/deprecated/html-variation-price.php:118 +#: templates/admin/html-variation-price.php:27 +#. translators: placeholder is trial period validation message if passed an +#. invalid value (e.g. "Trial period can not exceed 4 weeks") +msgctxt "Trial period dropdown's description in pricing fields" +msgid "" +"An optional period of time to wait before charging the first recurring " +"payment. Any sign up fee will still be charged at the outset of the " +"subscription. %s" +msgstr "" + +#: templates/admin/html-variation-price.php:67 +msgctxt "Subscription Length dropdown's description in pricing fields" +msgid "" +"Automatically expire the subscription after this length of time. This " +"length is in addition to any free trial or amount of time provided before a " +"synchronised first renewal date." +msgstr "" + #: templates/checkout/form-change-payment-method.php:20 -#: templates/emails/admin-new-renewal-order.php:35 -#: templates/emails/admin-new-switch-order.php:38 -#: templates/emails/admin-new-switch-order.php:76 -#: templates/emails/cancelled-subscription.php:54 -#: templates/emails/customer-completed-renewal-order.php:36 -#: templates/emails/customer-completed-switch-order.php:36 -#: templates/emails/customer-completed-switch-order.php:75 -#: templates/emails/customer-processing-renewal-order.php:31 -#: templates/emails/customer-renewal-invoice.php:42 +#: templates/emails/email-order-details.php:33 #: templates/myaccount/view-subscription.php:95 msgctxt "table headings in notification email" msgid "Product" msgstr "" #: templates/checkout/form-change-payment-method.php:21 -#: templates/emails/admin-new-renewal-order.php:36 -#: templates/emails/admin-new-switch-order.php:39 -#: templates/emails/admin-new-switch-order.php:77 -#: templates/emails/cancelled-subscription.php:55 -#: templates/emails/customer-completed-renewal-order.php:37 -#: templates/emails/customer-completed-switch-order.php:37 -#: templates/emails/customer-completed-switch-order.php:76 -#: templates/emails/customer-processing-renewal-order.php:32 -#: templates/emails/customer-renewal-invoice.php:43 +#: templates/emails/email-order-details.php:34 msgctxt "table headings in notification email" msgid "Quantity" msgstr "" @@ -3924,16 +5130,10 @@ msgctxt "table headings in notification email" msgid "Totals" msgstr "" -#: templates/emails/admin-new-renewal-order.php:37 -#: templates/emails/admin-new-switch-order.php:40 -#: templates/emails/admin-new-switch-order.php:78 #: templates/emails/cancelled-subscription.php:27 -#: templates/emails/cancelled-subscription.php:56 -#: templates/emails/customer-completed-renewal-order.php:38 -#: templates/emails/customer-completed-switch-order.php:38 -#: templates/emails/customer-completed-switch-order.php:77 -#: templates/emails/customer-processing-renewal-order.php:33 -#: templates/emails/customer-renewal-invoice.php:44 +#: templates/emails/email-order-details.php:35 +#: templates/emails/expired-subscription.php:27 +#: templates/emails/on-hold-subscription.php:27 msgctxt "table headings in notification email" msgid "Price" msgstr "" @@ -3943,43 +5143,73 @@ msgctxt "table headings in notification email" msgid "End of Prepaid Term" msgstr "" +#: templates/emails/expired-subscription.php:29 +msgctxt "table headings in notification email" +msgid "End Date" +msgstr "" + +#: templates/emails/on-hold-subscription.php:29 +msgctxt "table headings in notification email" +msgid "Date Suspended" +msgstr "" + #: templates/checkout/form-change-payment-method.php:55 msgctxt "text on button on checkout page" msgid "Change Payment Method" msgstr "" -#: templates/emails/admin-new-renewal-order.php:19 +#: templates/emails/admin-new-renewal-order.php:16 #: templates/emails/plain/admin-new-renewal-order.php:16 -#. translators: $1: customer's billing first name, $2: customer's billing last -#. name +#. translators: $1: customer's billing first name and last name msgctxt "Used in admin email: new renewal order" msgid "" -"You have received a subscription renewal order from %1$s %2$s. Their order " -"is as follows:" -msgstr "" - -#: templates/emails/admin-new-renewal-order.php:28 -#: templates/emails/customer-completed-renewal-order.php:29 -#: templates/emails/customer-processing-renewal-order.php:24 -#. translators: $1: order's order number, $2: date of order in
tags $3: order's order number +#. $4: date of order in tags $2: subscription's order +#. number +msgctxt "Used in email notification" +msgid "Subscription %1$s#%2$s%3$s" +msgstr "" + +#: templates/emails/plain/cancelled-subscription.php:44 +#: templates/emails/plain/expired-subscription.php:44 +#: templates/emails/plain/on-hold-subscription.php:40 #: templates/emails/plain/subscription-info.php:21 -#. translators: placeholder is edit post link for the subscription #. translators: placeholder is either view or edit url for the subscription msgctxt "in plain emails for subscription information" msgid "View Subscription: %s" @@ -4040,12 +5297,22 @@ msgctxt "in plain emails for subscription information" msgid "Price: %s" msgstr "" +#: templates/emails/plain/email-order-details.php:17 +msgctxt "date format for order date in notification emails" +msgid "jS F Y" +msgstr "" + #: templates/emails/plain/subscription-info.php:25 #: templates/emails/subscription-info.php:29 msgctxt "Used as end date for an indefinite subscription" msgid "When Cancelled" msgstr "" +#: templates/emails/subscription-info.php:27 +msgctxt "subscription number in email table. (eg: #106)" +msgid "#%s" +msgstr "" + #: templates/myaccount/my-subscriptions.php:54 #: templates/myaccount/related-orders.php:47 #: templates/myaccount/related-subscriptions.php:41 @@ -4085,125 +5352,89 @@ msgctxt "date on subscription updates list. Will be localized" msgid "l jS \\o\\f F Y, h:ia" msgstr "" -#: templates/myaccount/view-subscription.php:136 -#. translators: %1$s is the number of the file (only in plural!), %2$s: the -#. name of the file -msgctxt "Used as link text in view-subscription template" -msgid "Download file: %2$s" -msgid_plural "Download file %1$s: %2$s" -msgstr[0] "" -msgstr[1] "" - -#: templates/myaccount/view-subscription.php:233 -msgctxt "customer note" -msgid "Note:" -msgstr "" - -#: templates/myaccount/view-subscription.php:249 -#. translators: there is markup here, hence can't use Email: %s -msgctxt "heading in customer details on subscription detail page" -msgid "Email" -msgstr "" - -#: templates/myaccount/view-subscription.php:254 -#. translators: there is markup here, hence can't use Email: %s -msgctxt "heading in customer details on subscription detail page" -msgid "Tel" -msgstr "" - -#: templates/myaccount/view-subscription.php:249 -msgctxt "Used in data attribute for a td tag, escaped." -msgid "Email" -msgstr "" - -#: templates/myaccount/view-subscription.php:254 -msgctxt "Used in data attribute for a td tag, escaped." -msgid "Telephone" -msgstr "" - -#: wcs-functions.php:125 +#: wcs-functions.php:127 msgctxt "Error message while creating a subscription" msgid "Invalid date. The date must be a string and of the format: \"Y-m-d H:i:s\"." msgstr "" -#: wcs-functions.php:127 +#: wcs-functions.php:129 msgctxt "Error message while creating a subscription" msgid "Subscription start date must be before current day." msgstr "" -#: wcs-functions.php:132 +#: wcs-functions.php:134 msgctxt "Error message while creating a subscription" msgid "Invalid subscription customer_id." msgstr "" -#: wcs-functions.php:153 +#: wcs-functions.php:155 #. translators: placeholder is order date parsed by strftime msgctxt "The post title for the new subscription" msgid "Subscription – %s" msgstr "" -#: woocommerce-subscriptions.php:202 +#: woocommerce-subscriptions.php:207 msgctxt "custom post type setting" msgid "Add Subscription" msgstr "" -#: woocommerce-subscriptions.php:203 +#: woocommerce-subscriptions.php:208 msgctxt "custom post type setting" msgid "Add New Subscription" msgstr "" -#: woocommerce-subscriptions.php:204 +#: woocommerce-subscriptions.php:209 msgctxt "custom post type setting" msgid "Edit" msgstr "" -#: woocommerce-subscriptions.php:205 +#: woocommerce-subscriptions.php:210 msgctxt "custom post type setting" msgid "Edit Subscription" msgstr "" -#: woocommerce-subscriptions.php:206 +#: woocommerce-subscriptions.php:211 msgctxt "custom post type setting" msgid "New Subscription" msgstr "" -#: woocommerce-subscriptions.php:207 woocommerce-subscriptions.php:208 +#: woocommerce-subscriptions.php:212 woocommerce-subscriptions.php:213 msgctxt "custom post type setting" msgid "View Subscription" msgstr "" -#: woocommerce-subscriptions.php:211 +#: woocommerce-subscriptions.php:216 msgctxt "custom post type setting" msgid "No Subscriptions found in trash" msgstr "" -#: woocommerce-subscriptions.php:212 +#: woocommerce-subscriptions.php:217 msgctxt "custom post type setting" msgid "Parent Subscriptions" msgstr "" -#: woocommerce-subscriptions.php:279 +#: woocommerce-subscriptions.php:284 msgctxt "post status label including post count" msgid "Active (%s)" msgid_plural "Active (%s)" msgstr[0] "" msgstr[1] "" -#: woocommerce-subscriptions.php:280 +#: woocommerce-subscriptions.php:285 msgctxt "post status label including post count" msgid "Switched (%s)" msgid_plural "Switched (%s)" msgstr[0] "" msgstr[1] "" -#: woocommerce-subscriptions.php:281 +#: woocommerce-subscriptions.php:286 msgctxt "post status label including post count" msgid "Expired (%s)" msgid_plural "Expired (%s)" msgstr[0] "" msgstr[1] "" -#: woocommerce-subscriptions.php:282 +#: woocommerce-subscriptions.php:287 msgctxt "post status label including post count" msgid "Pending Cancellation (%s)" msgid_plural "Pending Cancellation (%s)" diff --git a/readme.txt b/readme.txt index b42e5a6..e5d7b5d 100644 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ Contributors: prospress, javorszky, jconroy, mattallan, thenbrent Tags: woocommerce, subscriptions, ecommerce, e-commerce, commerce, wordpress ecommerce Requires at least: 4.0 -Tested up to: 4.3 +Tested up to: 4.5 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html -WC requires at least: 2.3 -WC tested up to: 2.4 \ No newline at end of file +WC requires at least: 2.4 +WC tested up to: 2.6 \ No newline at end of file diff --git a/templates/admin/post-types/writepanels/order-shipping-html.php b/templates/admin/deprecated/order-shipping-html.php similarity index 100% rename from templates/admin/post-types/writepanels/order-shipping-html.php rename to templates/admin/deprecated/order-shipping-html.php diff --git a/templates/admin/post-types/writepanels/order-tax-html.php b/templates/admin/deprecated/order-tax-html.php similarity index 100% rename from templates/admin/post-types/writepanels/order-tax-html.php rename to templates/admin/deprecated/order-tax-html.php diff --git a/templates/admin/html-variation-price.php b/templates/admin/html-variation-price.php index b08c5f6..aa6cb72 100644 --- a/templates/admin/html-variation-price.php +++ b/templates/admin/html-variation-price.php @@ -1,6 +1,6 @@ I ?>