Reputation: 7580
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
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
Reputation: 7580
So I was able to make this work doing following.
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
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