/**
     * Trigger a notification
     * 
     * @access public
     * @param object $subscription
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($subscription, $args = array(), $send_to_admin = false)
    {
        if (!$subscription || !isset($subscription->last_order_id)) {
            return;
        }

        $order = new WC_Order($subscription->last_order_id);

        if (!$order) {
            return;
        }

        $this->object = $order;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = $this->object->billing_email;
        }

        // Replace macros
        $this->find[] = '{order_number}';
        $this->replace[] = $this->object->get_order_number();

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        // Get next action and next action date
        $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_payment', $subscription->id);
        $next_action_is_overdue = false;

        if ($subscription->calculate_overdue_time()) {
            $next_action = __('marked overdue', 'subscriptio');
            $next_action_is_overdue = true;
            $subsequent_action = $subscription->calculate_suspension_time() > 0 ? __('suspension', 'subscriptio') : __('cancellation', 'subscriptio');
        }
        else if ($subscription->calculate_suspension_time() > 0) {
            $next_action = __('suspended', 'subscriptio');
        }
        else {
            $next_action = __('cancelled', 'subscriptio');
        }

        $this->template_variables = array(
            'subscription'              => $subscription,
            'order'                     => $this->object,
            'email_heading'             => $this->get_heading(),
            'sent_to_admin'             => false,
            'next_action'               => $next_action,
            'next_action_datetime'      => $next_action_datetime,
            'next_action_is_overdue'    => $next_action_is_overdue,
            'subsequent_action'         => isset($subsequent_action) ? $subsequent_action : '',
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
    /**
     * Trigger a notification
     * 
     * @access public
     * @param object $subscription
     * @param array $args
     * @param bool $send_to_admin
     * @return void
     */
    public function trigger($subscription, $args = array(), $send_to_admin = false)
    {
        if (!$subscription || !isset($subscription->last_order_id)) {
            return;
        }

        $order = new WC_Order($subscription->last_order_id);

        if (!$order) {
            return;
        }

        $this->object = $subscription;

        if ($send_to_admin) {
            $this->recipient = get_option('admin_email');
        }
        else {
            $this->recipient = get_user_meta($subscription->user_id, 'billing_email', true);
        }

        // Check if this email type is enabled, recipient is set and we are not on a development website
        if (!$this->is_enabled() || !$this->get_recipient() || !Subscriptio::is_main_site()) {
            return;
        }

        // Get next action date and time
        $next_action_datetime = Subscriptio_Scheduler::get_scheduled_event_datetime('subscriptio_scheduled_cancellation', $subscription->id);

        $this->template_variables = array(
            'subscription'          => $this->object,
            'order'                 => $order,
            'email_heading'         => $this->get_heading(),
            'sent_to_admin'         => false,
            'next_action_datetime'  => $next_action_datetime,
        );

        $this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
    }
                <p>
                    <strong><?php _e('Suspension:', 'subscriptio'); ?></strong>
                    <?php echo Subscriptio::get_adjusted_datetime($scheduled_suspension);
                    $scheduled_events = true; ?>
                </p>
            <?php endif; ?>

            <?php if ($scheduled_cancellation = Subscriptio_Scheduler::get_scheduled_event_timestamp('subscriptio_scheduled_cancellation', $subscription->id)): ?>
                <p>
                    <strong><?php _e('Cancellation:', 'subscriptio'); ?></strong>
                    <?php echo Subscriptio::get_adjusted_datetime($scheduled_cancellation);
                    $scheduled_events = true; ?>
                </p>
            <?php endif; ?>

            <?php if ($scheduled_expiration = Subscriptio_Scheduler::get_scheduled_event_timestamp('subscriptio_scheduled_expiration', $subscription->id)): ?>
                <p>
                    <strong><?php _e('Expiration:', 'subscriptio'); ?></strong>
                    <?php echo Subscriptio::get_adjusted_datetime($scheduled_expiration);
                    $scheduled_events = true; ?>
                </p>
            <?php endif; ?>

            <?php if (!$scheduled_events): ?>
                <p class="subscriptio_nothing_to_display">
                    <?php _e('No events scheduled.', 'subscriptio'); ?>
                </p>
            <?php endif; ?>

        </div>
    </div>
    /**
     * Create renewal order
     * Based on the WooCommerce procedure found in class-wc-checkout.php
     * 
     * @access public
     * @param object $subscription
     * @return int
     */
    public static function create_renewal_order($subscription)
    {
        // Get instance of main plugin class to access settings
        $subscriptio = Subscriptio::get_instance();

        // Since WooCommerce 2.2 order statuses are stored as post statuses
        $post_status = Subscriptio::wc_version_gte('2.2') ? 'wc-pending' : 'publish';

        // Prepare post properties
        $order_data = array(
            'post_type' 	=> 'shop_order',
            'post_title' 	=> sprintf(__('Order &ndash; %s', 'subscriptio'), strftime(_x('%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'subscriptio'))),
            'post_status' 	=> $post_status,
            'ping_status'	=> 'closed',
            'post_excerpt' 	=> $subscription->renewal_customer_note,
            'post_author' 	=> 1,
            'post_password'	=> uniqid('order_'),
        );

        // Insert post into database
        $order_id = wp_insert_post($order_data, true);

        // Successfully inserted order post?
        if (is_wp_error($order_id)) {
            throw new Exception(__('Unable to create renewal order - failed inserting post.', 'subscriptio'));
        }

        // Load user meta
        $user_meta = Subscriptio::unwrap_post_meta(get_user_meta($subscription->user_id));

        // Insert billing and shipping details
        $billing_shipping_fields = array(
            'billing'  => array(
                '_first_name',
                '_last_name',
                '_company',
                '_address_1',
                '_address_2',
                '_city',
                '_state',
                '_postcode',
                '_country',
                '_email',
                '_phone',
            ),
        );

        // Check if subscription needs shipping
        if ($subscription->needs_shipping()) {
            $billing_shipping_fields['shipping'] = array(
                '_first_name',
                '_last_name',
                '_company',
                '_address_1',
                '_address_2',
                '_city',
                '_state',
                '_postcode',
                '_country',
            );
        }

        // Iterate over billing/shipping fields and save them
        foreach ($billing_shipping_fields as $type => $fields) {
            foreach ($fields as $field) {

                // Billing fields
                if ($type == 'billing' && isset($user_meta[$type . $field])) {
                    $field_value = $user_meta[$type . $field];
                }

                // Shipping fields
                else if ($type == 'shipping' && isset($subscription->shipping_address['_' . $type . $field])) {
                    $field_value = $subscription->shipping_address['_' . $type . $field];
                }

                // In case some field does not exist
                else {
                    $field_value = '';
                }

                // Save field to post meta
                update_post_meta($order_id, '_' . $type . $field, $field_value);
            }
        }

        // Add other meta fields
        $other_meta_fields = array(
            '_order_shipping'       => $subscription->renewal_order_shipping,
            '_order_shipping_tax'   => $subscription->renewal_order_shipping_tax,
            '_cart_discount'        => $subscription->renewal_cart_discount,
            '_order_discount'       => $subscription->renewal_order_discount,
            '_order_tax'            => $subscription->renewal_order_tax,
            '_order_total'          => $subscription->renewal_order_total,
            '_customer_user'        => $subscription->user_id,
            '_order_currency'       => $subscription->renewal_order_currency,
            '_order_key'            => 'wc_' . apply_filters('woocommerce_generate_order_key', uniqid('order_')),
            '_prices_include_tax'   => $subscription->renewal_prices_include_tax,
            '_customer_ip_address'  => $subscription->renewal_customer_ip_address,
            '_customer_user_agent'  => $subscription->renewal_customer_user_agent,
            '_payment_method'       => '',  // Not yet paid
            '_payment_method_title' => '',  // Not yet paid
            '_subscriptio_renewal'  => 'yes',
        );

        foreach ($other_meta_fields as $field_key => $field_value) {
            update_post_meta($order_id, $field_key, $field_value);
        }

        // Check if subscription product is variable
        $product_id_to_use = !empty($subscription->variation_id) ? $subscription->variation_id : $subscription->product_id;

        // Check if product still exists
        if (Subscriptio::product_is_active($product_id_to_use)) {

            // Load product object
            $product = new WC_Product($product_id_to_use);

            // Get product name
            $product_title = $product->get_title();

            // Update product name on subscription if it was changed
            if ($product_title != $subscription->product_name) {
                $subscription->update_subscription_details(array(
                    'product_name'  => $product_title,
                ));
            }
        }

        // If not - use saved product "snapshot" from previous order
        else {
            $product_title = $subscription->product_name;
        }

        // Add line item (product) to order
        $item_id = wc_add_order_item($order_id, array(
            'order_item_name'   => $product_title,
            'order_item_type'   => 'line_item',
        ));

        if (!$item_id) {
            throw new Exception(__('Unable to add product to renewal order.', 'subscriptio'));
        }

        // Add line item meta
        $item_meta = array(
            '_qty'                  => !empty($subscription->quantity) ? $subscription->quantity : 1,
            '_tax_class'            => $subscription->renewal_tax_class,
            '_product_id'           => $subscription->product_id,
            '_variation_id'         => !empty($subscription->variation_id) ? $subscription->variation_id : '',
            '_line_subtotal'        => wc_format_decimal($subscription->renewal_line_subtotal),
            '_line_subtotal_tax'    => wc_format_decimal($subscription->renewal_line_subtotal_tax),
            '_line_total'           => wc_format_decimal($subscription->renewal_line_total),
            '_line_tax'             => wc_format_decimal($subscription->renewal_line_tax),
        );

        foreach ($item_meta as $item_meta_key => $item_meta_value) {
            wc_add_order_item_meta($item_id, $item_meta_key, $item_meta_value);
        }

        // Save shipping info (if any)
        if (!empty($subscription->shipping)) {
            $shipping_item_id = wc_add_order_item($order_id, array(
                'order_item_name'   => $subscription->shipping['name'],
                'order_item_type'   => 'shipping',
            ));

            wc_add_order_item_meta($shipping_item_id, 'method_id', $subscription->shipping['method_id']);
            wc_add_order_item_meta($shipping_item_id, 'cost', wc_format_decimal($subscription->shipping['cost']));
        }

        // Save taxes (if any)
        foreach ($subscription->taxes as $tax) {
            $tax_item_id = wc_add_order_item($order_id, array(
                'order_item_name'   => $tax['name'],
                'order_item_type'   => 'tax',
            ));

            wc_add_order_item_meta($tax_item_id, 'rate_id', $tax['rate_id']);
            wc_add_order_item_meta($tax_item_id, 'label', $tax['label']);
            wc_add_order_item_meta($tax_item_id, 'compound', $tax['compound']);
            wc_add_order_item_meta($tax_item_id, 'tax_amount', wc_format_decimal($tax['tax_amount'], 4));
            wc_add_order_item_meta($tax_item_id, 'shipping_tax_amount', wc_format_decimal($tax['shipping_tax_amount'], 4));
        }

        // Schedule payment due reminders
        if ($payment_due_timestamp = wp_next_scheduled('subscriptio_scheduled_payment', $subscription->id)) {
            foreach ($subscription->get_reminders('pre_payment_due', $payment_due_timestamp) as $timestamp) {
                Subscriptio_Scheduler::schedule_reminder($subscription->id, $timestamp);
            }
        }

        // Update appropriate subscription fields with new order id
        $subscription->update_subscription_details(array(
            'last_order_id' => $order_id,
            'all_order_ids' => $order_id,
        ));

        // Create a new order object
        $order = new WC_Order($order_id);

        // Set status to pending (pre- WooCommerce 2.2)
        if (!Subscriptio::wc_version_gte('2.2')) {
            $order->update_status('pending');
        }

        // Send New Order email
        Subscriptio_Mailer::send('new_order', $order);

        return $order_id;
    }
Exemple #5
0
    /**
     * Post deleted
     * 
     * @access public
     * @param int $post_id
     * @return void
     */
    public function post_deleted($post_id)
    {
        global $post_type;

        if ($post_type != 'subscription') {
            return;
        }

        // Unschedule all events
        Subscriptio_Scheduler::unschedule_all($post_id);

        // Write to transaction log
        $transaction = new Subscriptio_Transaction(null, 'subscription_deleted', $post_id);
        $transaction->update_result('success');
        $transaction->update_note(__('Subscription manually deleted by administrator.', 'subscriptio'));
    }
    /**
     * Load ONLY valid subscription (subscription exists, not in trash, user exists etc)
     * 
     * @access public
     * @param $subscription_id
     * @param $transaction
     * @return mixed
     */
    public static function get_valid_subscription($subscription_id, $transaction = null)
    {
        // Check if subscription ID was passed in
        if (!is_numeric($subscription_id) || $subscription_id < 1) {

            if ($transaction) {
                $transaction->update_result('error');
                $transaction->update_note(__('Subscription ID unknown.', 'subscriptio'), true);
            }

            return false;
        }

        // Update transaction with subscription ID
        if ($transaction) {
            $transaction->add_subscription_id($subscription_id);
        }

        // Get subscription by its ID
        $subscription = self::get_by_id($subscription_id);

        // Check if subscription exists
        if (!isset($subscription->id)) {

            if ($transaction) {
                $transaction->update_result('error');
                $transaction->update_note(__('Subscription no longer exists.', 'subscriptio'), true);
            }

            return false;
        }

        // Check if subscription is not cancelled or expired
        if (in_array($subscription->status, array('cancelled', 'expired'))) {

            if ($transaction) {
                $transaction->update_result('error');
                $transaction->update_note(__('Subscription is cancelled or expired.', 'subscriptio'), true);
            }

            return false;
        }

        // Check if user exists
        if (!isset($subscription->user_id) || !($user = get_userdata($subscription->user_id))) {

            if ($transaction) {
                $transaction->update_result('error');
                $transaction->update_note(__('User no longer exists.', 'subscriptio'), true);
            }

            return false;
        }

        // Check if subscription shouldn't be expired (better be safe than sorry...)
        if (!defined('SUBSCRIPTIO_DOING_EXPIRATION') && $subscription->expires && time() >= $subscription->expires) {

            // Expire the subscription now
            Subscriptio_Scheduler::scheduled_expiration($subscription->id);

            if ($transaction) {
                $transaction->update_result('error');
                $transaction->update_note(__('Subscription was already expired. Scheduled tasks failing?', 'subscriptio'), true);
            }

            return false;
        }

        // Update transaction with product and variation IDs
        if ($transaction) {
            $transaction->add_product_id($subscription->product_id);
            $transaction->add_variation_id($subscription->variation_id);
        }

        // All tests passed.. Return subscription object
        return $subscription;
    }