/** * Order API Modification #1: * * Restore virtual status and weights/dimensions of bundle containers/children depending on the "per-item pricing" and "per-item shipping" settings. * Virtual containers/children are assigned a zero weight and tiny dimensions in order to maintain the value of the associated item in shipments (for instance, when a bundle has a static price but is shipped per item). * * Restore bundle container price - equal to base price in "per-item pricing" mode. * * @param WC_Product $product * @param array $item * @param WC_Order $order * @return WC_Product */ public function get_product_from_item($product, $item, $order) { if (apply_filters('woocommerce_bundles_filter_product_from_item', false, $order)) { // Restore base price. if (!empty($product) && $product->product_type === 'bundle' && isset($item['bundled_items']) && isset($item['per_product_pricing']) && $item['per_product_pricing'] === 'yes') { $product->price = $product->get_base_price(); $product->regular_price = $product->get_base_regular_price(); $product->sale_price = $product->get_base_sale_price(); } // Modify shipping properties. if (!empty($product) && isset($item['stamp']) && isset($item['bundled_shipping'])) { if ($item['bundled_shipping'] === 'yes') { if (isset($item['bundled_weight'])) { $product->weight = $item['bundled_weight']; } } else { // Virtual container converted to non-virtual with zero weight and tiny dimensions if it has non-virtual bundled children. if (isset($item['bundled_items']) && isset($item['bundle_cart_key'])) { $bundle_key = $item['bundle_cart_key']; $non_virtual_child_exists = false; self::$override_order_items_filters = true; foreach ($order->get_items('line_item') as $child_item_id => $child_item) { if (isset($child_item['bundled_by']) && $child_item['bundled_by'] === $bundle_key && isset($child_item['bundled_shipping']) && $child_item['bundled_shipping'] === 'yes') { $non_virtual_child_exists = true; break; } } self::$override_order_items_filters = false; if ($non_virtual_child_exists) { $product->virtual = 'no'; } } $product->weight = 0; $product->length = $product->height = $product->width = 0.001; } } } return $product; }
/** * Filters get_base_price to include component discounts. * * @param double $price * @param WC_Product $product * @return string */ public function filter_show_product_get_base_price($price, $product) { if (!empty($this->filter_params)) { if ($price === '') { return $price; } if (!$this->filter_params['per_product_pricing']) { return (double) 0; } if (apply_filters('woocommerce_composited_product_discount_from_regular', true, $this->filter_params['component_id'], $this->filter_params['composite_id'])) { $regular_price = $product->get_base_regular_price(); } else { $regular_price = $price; } $discount = $this->filter_params['discount']; $price = empty($discount) ? $price : (empty($regular_price) ? $regular_price : round((double) $regular_price * (100 - $discount) / 100, wc_cp_price_num_decimals())); } return $price; }
/** * Filter get_base_sale_price() calls to take price overrides into account. * * @param double $sale_price * @param WC_Product $product * @return double */ public static function filter_get_base_sale_price($sale_price, $product) { $subscription_scheme = WCS_ATT_Scheme_Prices::$price_overriding_scheme; if ($subscription_scheme) { WCS_ATT_Scheme_Prices::$price_overriding_scheme = false; $prices_array = array('price' => $product->get_base_price(), 'regular_price' => $product->get_base_regular_price(), 'sale_price' => $sale_price); WCS_ATT_Scheme_Prices::$price_overriding_scheme = $subscription_scheme; $overridden_prices = WCS_ATT_Scheme_Prices::get_subscription_scheme_prices($prices_array, $subscription_scheme); $sale_price = $overridden_prices['sale_price']; } return $sale_price; }