/** * When a new order is inserted, add subscriptions related order meta. * * @since 1.0 */ public static function add_order_meta($order_id, $posted) { global $woocommerce; if (!WC_Subscriptions_Cart::cart_contains_subscription_renewal('child') && WC_Subscriptions_Order::order_contains_subscription($order_id)) { // This works because the 'woocommerce_add_order_item_meta' runs before the 'woocommerce_checkout_update_order_meta' hook // Set the recurring totals so totals display correctly on order page update_post_meta($order_id, '_order_recurring_discount_cart', WC_Subscriptions_Cart::get_recurring_discount_cart()); update_post_meta($order_id, '_order_recurring_discount_cart_tax', WC_Subscriptions_Cart::get_recurring_discount_cart_tax()); update_post_meta($order_id, '_order_recurring_discount_total', WC_Subscriptions_Cart::get_recurring_discount_total()); update_post_meta($order_id, '_order_recurring_shipping_tax_total', WC_Subscriptions_Cart::get_recurring_shipping_tax_total()); update_post_meta($order_id, '_order_recurring_shipping_total', WC_Subscriptions_Cart::get_recurring_shipping_total()); update_post_meta($order_id, '_order_recurring_tax_total', WC_Subscriptions_Cart::get_recurring_total_tax()); update_post_meta($order_id, '_order_recurring_total', WC_Subscriptions_Cart::get_recurring_total()); // Set the recurring payment method - it starts out the same as the original by may change later update_post_meta($order_id, '_recurring_payment_method', get_post_meta($order_id, '_payment_method', true)); update_post_meta($order_id, '_recurring_payment_method_title', get_post_meta($order_id, '_payment_method_title', true)); $order = new WC_Order($order_id); $order_fees = $order->get_fees(); // the fee order items have already been set, we just need to to add the recurring total meta $cart_fees = $woocommerce->cart->get_fees(); foreach ($order->get_fees() as $item_id => $order_fee) { // Find the matching fee in the cart foreach ($cart_fees as $fee_index => $cart_fee) { if (sanitize_title($order_fee['name']) == $cart_fee->id) { woocommerce_add_order_item_meta($item_id, '_recurring_line_total', wc_format_decimal($cart_fee->recurring_amount)); woocommerce_add_order_item_meta($item_id, '_recurring_line_tax', wc_format_decimal($cart_fee->recurring_tax)); unset($cart_fees[$fee_index]); break; } } } // Get recurring taxes into same format as _order_taxes $order_recurring_taxes = array(); foreach (WC_Subscriptions_Cart::get_recurring_taxes() as $tax_key => $tax_amount) { $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => WC_Tax::get_rate_code($tax_key), 'order_item_type' => 'recurring_tax')); if ($item_id) { wc_add_order_item_meta($item_id, 'rate_id', $tax_key); wc_add_order_item_meta($item_id, 'label', WC_Tax::get_rate_label($tax_key)); wc_add_order_item_meta($item_id, 'compound', absint(WC_Tax::is_compound($tax_key) ? 1 : 0)); wc_add_order_item_meta($item_id, 'tax_amount', wc_format_decimal(isset(WC()->cart->recurring_taxes[$tax_key]) ? WC()->cart->recurring_taxes[$tax_key] : 0)); wc_add_order_item_meta($item_id, 'shipping_tax_amount', wc_format_decimal(isset(WC()->cart->recurring_shipping_taxes[$tax_key]) ? WC()->cart->recurring_shipping_taxes[$tax_key] : 0)); } } $payment_gateways = $woocommerce->payment_gateways->payment_gateways(); if ('yes' == get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')) { update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true'); } elseif (isset($payment_gateways[$posted['payment_method']]) && !$payment_gateways[$posted['payment_method']]->supports('subscriptions')) { update_post_meta($order_id, '_wcs_requires_manual_renewal', 'true'); } $cart_item = WC_Subscriptions_Cart::cart_contains_subscription_renewal(); if (isset($cart_item['subscription_renewal']) && 'parent' == $cart_item['subscription_renewal']['role']) { update_post_meta($order_id, '_original_order', $cart_item['subscription_renewal']['original_order']); } // WC 2.1+ if (!WC_Subscriptions::is_woocommerce_pre('2.1')) { // Recurring coupons if ($applied_coupons = $woocommerce->cart->get_coupons()) { foreach ($applied_coupons as $code => $coupon) { if (!isset($woocommerce->cart->recurring_coupon_discount_amounts[$code])) { continue; } $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $code, 'order_item_type' => 'recurring_coupon')); // Add line item meta if ($item_id) { woocommerce_add_order_item_meta($item_id, 'discount_amount', isset($woocommerce->cart->recurring_coupon_discount_amounts[$code]) ? $woocommerce->cart->recurring_coupon_discount_amounts[$code] : 0); } } } // Add recurring shipping order items if (WC_Subscriptions_Cart::cart_contains_subscriptions_needing_shipping()) { $packages = $woocommerce->shipping->get_packages(); $checkout = $woocommerce->checkout(); foreach ($packages as $i => $package) { if (isset($package['rates'][$checkout->shipping_methods[$i]])) { $method = $package['rates'][$checkout->shipping_methods[$i]]; $item_id = woocommerce_add_order_item($order_id, array('order_item_name' => $method->label, 'order_item_type' => 'recurring_shipping')); if ($item_id) { woocommerce_add_order_item_meta($item_id, 'method_id', $method->id); woocommerce_add_order_item_meta($item_id, 'cost', WC_Subscriptions::format_total($method->cost)); woocommerce_add_order_item_meta($item_id, 'taxes', array_map('wc_format_decimal', $method->taxes)); do_action('woocommerce_subscriptions_add_recurring_shipping_order_item', $order_id, $item_id, $i); } } } } // Remove shipping on original order if it was added but is not required if (!WC_Subscriptions_Cart::charge_shipping_up_front()) { foreach ($order->get_shipping_methods() as $order_item_id => $shipping_method) { woocommerce_update_order_item_meta($order_item_id, 'cost', WC_Subscriptions::format_total(0)); } } } else { update_post_meta($order_id, '_recurring_shipping_method', get_post_meta($order_id, '_shipping_method', true), true); update_post_meta($order_id, '_recurring_shipping_method_title', get_post_meta($order_id, '_shipping_method_title', true), true); } } }
/** * Returns an array of order items in a TaxCloud friendly format * * array( * [item_key] => array ( * [TIC] => TIC or empty string * [ItemID] => Product ID * [Index] => Item index (can be left blank for our purposes; re-assigned in generate_lookup_data) * [Type] => Item type (Values: cart, fee, shipping) * [Price] => The item price * [Qty] => The quantity of the item being purchased * ) * ) * * @since 4.2 * @return (array) array of items (see above for structure) */ private function get_items_array() { $items = $this->cart->cart_contents; $based_on = WC_WooTax::get_option('tax_based_on'); $final_items = array(); // Add cart items foreach ($items as $item_key => $item) { $product = $item['data']; // Get product TIC $tic_raw = get_post_meta($product->id, 'wootax_tic', true); $tic = $tic_raw == false ? '' : trim($tic_raw); // Get product ID, Qty, and Price $item_id = $item_key; $product_price = $item['line_total'] / $item['quantity']; if ($based_on == 'item-price' || !$based_on) { $qty = $item['quantity']; $price = $product_price; } else { $qty = 1; $price = $product_price * $item['quantity']; } // Add to final items array $final_items[$item_key] = array('Index' => NULL, 'ItemID' => $item_id, 'Price' => $price, 'Qty' => $qty, 'Type' => 'cart'); // Only add TIC if it is set if (!empty($tic)) { $final_items[$item_key]['TIC'] = $tic; } } // Add fees $fees = $this->cart->get_fees(); if (is_array($fees)) { foreach ($fees as $ind => $fee) { // Skip if not taxable (TODO: phase this out too?) if (isset($fee->taxable) && !$fee->taxable) { continue; } // Get fee identifier (fee index since we are in checkout) $fee_id = $fee->id; // Get fee amount $fee->amount $amt = $fee->amount; // Add to final items array $final_items[$fee_id] = array('Index' => NULL, 'ItemID' => $fee_id, 'TIC' => WT_FEE_TIC, 'Qty' => 1, 'Price' => $amt, 'Type' => 'fee'); } } // Add shipping costs $shipping_total = $this->cart->shipping_total; if ($this->is_subscription) { if (!WC_Subscriptions_Cart::charge_shipping_up_front() && (WC_Subscriptions_Cart::get_calculation_type() == 'sign_up_fee_total' || WC_Subscriptions_Cart::get_calculation_type() == 'free_trial_total')) { $shipping_total = 0; } } if ($shipping_total > 0) { // Add a shipping item to the final items array (we assume that only one shipping method is being used per order) $final_items[WT_SHIPPING_ITEM] = array('Index' => NULL, 'ItemID' => WT_SHIPPING_ITEM, 'TIC' => WT_SHIPPING_TIC, 'Qty' => 1, 'Price' => $shipping_total, 'Type' => 'shipping'); } return $final_items; }