/** * Shipping fix - ensure that non-virtual containers/children, which are shipped, have a valid price that can be used for insurance calculations. * Additionally, bundled item weights may have to be added in the container. * * Note: If you charge a static price for the bundle but ship bundled items individually, the only working solution is to spread the total value among the bundled items. * * @param array $packages * @return array */ function woo_bundles_shipping_packages_fix($packages) { if (!empty($packages)) { foreach ($packages as $package_key => $package) { if (!empty($package['contents'])) { foreach ($package['contents'] as $cart_item => $cart_item_data) { if (isset($cart_item_data['bundled_items'])) { $bundle = clone $cart_item_data['data']; $bundle_qty = $cart_item_data['quantity']; // Physical container (bundled shipping): // - if the container is priced per-item, sum the prices of the children into the parent // - optionally, append the weight of the children into the parent if (!$bundle->is_shipped_per_product()) { $bundled_value = $bundle->get_price(); $bundled_weight = 0; foreach ($cart_item_data['bundled_items'] as $child_item_key) { if (isset($package['contents'][$child_item_key])) { $bundled_product = clone $package['contents'][$child_item_key]['data']; $bundled_product_qty = $package['contents'][$child_item_key]['quantity']; if (isset($bundled_product->bundled_value)) { $bundled_value += $bundled_product->bundled_value * $bundled_product_qty; $bundled_product->price = 0; $packages[$package_key]['contents'][$child_item_key]['data'] = $bundled_product; } if (isset($bundled_product->bundled_weight)) { $bundled_weight += $bundled_product->bundled_weight * $bundled_product_qty; } } } $bundle->price = $bundled_value / $bundle_qty; $bundle->weight += $bundled_weight / $bundle_qty; if (isset($bundle->bundled_weight)) { $bundle->bundled_weight += $bundled_weight / $bundle_qty; } if (isset($bundle->bundled_value)) { $bundle->bundled_value += $bundled_value / $bundle_qty; } $packages[$package_key]['contents'][$cart_item]['data'] = $bundle; // Virtual container (non-bundled shipping enabled) that is priced statically: // Distribute the price of the parent uniformly among the children } elseif ($bundle->is_shipped_per_product() && !$bundle->is_priced_per_product()) { $total_value = $bundle->get_price() * $bundle_qty; $child_count = 0; $bundled_items = array(); foreach ($cart_item_data['bundled_items'] as $child_item_key) { if (isset($package['contents'][$child_item_key])) { $bundled_product = $package['contents'][$child_item_key]['data']; $bundled_product_qty = $package['contents'][$child_item_key]['quantity']; if ($bundled_product->needs_shipping()) { $child_count += $bundled_product_qty; $total_value += $bundled_product->get_price() * $bundled_product_qty; $bundled_items[] = $child_item_key; } } } foreach ($bundled_items as $child_item_key) { $bundled_product = clone $package['contents'][$child_item_key]['data']; $bundled_product->price = round($total_value / $child_count, wc_bundles_get_price_decimals()); $packages[$package_key]['contents'][$child_item_key]['data'] = $bundled_product; } $bundle->price = 0; $packages[$package_key]['contents'][$cart_item]['data'] = $bundle; } } } } } } return $packages; }
/** * Filter get_price() calls for bundled products to include discounts. * * @param double $price unmodified price * @param WC_Product $product the bundled product * @return double modified price */ function get_price($price, $product) { if ($product->id !== $this->product->id || $price === '') { return $price; } if (!$this->is_priced_per_product()) { return 0; } if (apply_filters('woocommerce_bundled_item_discount_from_regular', true, $this)) { $regular_price = $product->get_regular_price(); } else { $regular_price = $price; } $discount = $this->get_discount(); $bundled_item_price = empty($discount) ? (double) $price : round((double) $regular_price * (100 - $discount) / 100, wc_bundles_get_price_decimals()); $product->bundled_item_price = $bundled_item_price; return apply_filters('woocommerce_bundled_item_price', $bundled_item_price, $product, $discount); }
/** * Frontend scripts. * * @return void */ function woo_bundles_frontend_scripts() { global $woocommerce_bundles; $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; wp_register_script('wc-add-to-cart-bundle', $woocommerce_bundles->woo_bundles_plugin_url() . '/assets/js/add-to-cart-bundle' . $suffix . '.js', array('jquery', 'wc-add-to-cart-variation'), $woocommerce_bundles->version, true); wp_register_style('wc-bundle-css', $woocommerce_bundles->woo_bundles_plugin_url() . '/assets/css/bundles-frontend.css', false, $woocommerce_bundles->version); wp_register_style('wc-bundle-style', $woocommerce_bundles->woo_bundles_plugin_url() . '/assets/css/bundles-style.css', false, $woocommerce_bundles->version); wp_enqueue_style('wc-bundle-style'); $params = array('i18n_free' => __('Free!', 'woocommerce'), 'i18n_total' => __('Total', 'woocommerce-product-bundles') . ': ', 'i18n_subtotal' => __('Subtotal', 'woocommerce-product-bundles') . ': ', 'i18n_partially_out_of_stock' => __('Insufficient stock', 'woocommerce-product-bundles'), 'i18n_partially_on_backorder' => __('Available on backorder', 'woocommerce-product-bundles'), 'i18n_select_options' => sprintf(__('<p class="price"><span class="bundle_error">%s</span></p>', 'woocommerce-product-bundles'), __('To continue, please choose product options…', 'woocommerce-product-bundles')), 'i18n_unavailable_text' => sprintf(__('<p class="price"><span class="bundle_error">%s</span></p>', 'woocommerce-product-bundles'), __('Sorry, this product cannot be purchased at the moment.', 'woocommerce-product-bundles')), 'currency_symbol' => get_woocommerce_currency_symbol(), 'currency_position' => esc_attr(stripslashes(get_option('woocommerce_currency_pos'))), 'currency_format_num_decimals' => wc_bundles_get_price_decimals(), 'currency_format_decimal_sep' => esc_attr(stripslashes(get_option('woocommerce_price_decimal_sep'))), 'currency_format_thousand_sep' => esc_attr(stripslashes(get_option('woocommerce_price_thousand_sep'))), 'currency_format_trim_zeros' => false == apply_filters('woocommerce_price_trim_zeros', false) ? 'no' : 'yes'); wp_localize_script('wc-add-to-cart-bundle', 'wc_bundle_params', $params); }