Yalamber
Yalamber

Reputation: 7580

Updating WooCommerce Subscriptions Order line Items programmatically

I am trying to allow users to update line items of their subscriptions from their my account panel. I am able to get their subscription from subscription id and show them update form. Right now I show them with product items in their subscription that I got through

$subscription = wcs_get_subscription($_GET['subscription']);
$subscription_items = $subscription->get_items();

What I am trying to do is allow users to update quantities of their product. So If they update quantity I want to update the subscription's item quantity so that future orders are generated with updated quantity. I saw there is update_product method in WC_Abstract_Order class. I think this can be used but I am confused on this note in comments:

* Update a line item for the order.
*
* Note this does not update order totals.

Do I need to recalculate totals when I use this? Also I needed to remove line item when quantity was 0. Is that possible?

As I do not see a remove item method.

Thanks

Upvotes: 2

Views: 7752

Answers (3)

vorwerg-ni
vorwerg-ni

Reputation: 177

Its an old thread but in case its of any help to other people. You can just use the $subscription->remove_item function and then $subscription->save.

In your case:

$item_ids_to_remove = array();
// 1. get the item ids that should be removed
foreach ( $subscription->get_items() as $item ) {
    if ($item->get_quantity() == 0) {
        $item_ids_to_remove[] = $item->get_id();
    }
}
// 2. remove the items from the subscription
foreach ($item_ids_to_remove as $item_id_to_remove) {
    $subscription->remove_item($item_id_to_remove);
}
// 3. recalculate totals (incl. tax) and save
$subscription->calculate_totals();
$subscription->save();

Upvotes: 0

Yalamber
Yalamber

Reputation: 7580

So I was able to make this work doing following.

  1. Remove all order items from subscription object.
  2. Run through the $_POST to get changed quantity
  3. Add product to subscription again.

note: I am using custom field price_level as it was dynamically priced during subscription and we wanted to use it so that price was same as when they subscribed.

    //remove product items
    $subscription->remove_order_items('line_item');
    //add product item again
    foreach($_POST['quantity'] as $product_id => $qty) {
        if($qty > 0) {
            //we will need to set dynamic prices based on cusotm field
            $price_level = get_field('coffee_price_level', $subscription->id);
            //Get the product
            $product = wc_get_product($product_id);
            //set the price
            $product->set_price(floatval($price_level));
            $tax = ($product->get_price_including_tax()-$product->get_price_excluding_tax())*$qty;
            //subscription item price level
            $subscription->add_product($product, $qty, array(
                'totals' => array(
                    'subtotal'     => $product->get_price(),
                    'subtotal_tax' => $tax,
                    'total'        => $product->get_price(),
                    'tax'          => $tax,
                    'tax_data'     => array( 'subtotal' => array(1=>$tax), 'total' => array(1=>$tax) )
                )
            ));
        }
    }

Upvotes: 6

LoicTheAztec
LoicTheAztec

Reputation: 253901

Normally in woocommerce when an order is generated after payment (I mean checkout => thankyou), you can't edit anymore the order details. Updating quantities, removing/adding items are WC cart methods.

With subscriptions plugin, with each initial shop_order post-type, there is an initial shop_subscription post-type and a scheduled-action post-type generated at the same time (and post IDs follow each other). For example:

Initial (post type) 'shop_order' -> ID is        412
Initial (post type) 'shop_subscription' -> ID is 413  (and 'post_parent': 412)
Initial (post type) 'scheduled-action' -> ID is  414

You can see that in your database wp_posts table.

We could have updated the total in wp_postmeta table for 'post_id' => '413' with the corresponding meta_key '_order_total' using in this case the update_post_meta() function.

BUT this will not work, because the next scheduled subscription payment is handled by the payment gateway (paypal or others) and you can't change any amount of that subscription.

WooCommerce will just generate the new order triggered by this payment gateway, when a scheduled subscription is due.

The only way is to cancel the subscription and generate a new process from the beginning…

Upvotes: 3

Related Questions