/** * Filter the product retruned by `WC_Order::woocommerce_get_product_from_item()` * to re-calculate a Measurement Price Calculator product's weight based on the * selected measurements. This function ensures that the "Weight" calculator * type is handled appropriately as well. * * @param \WC_Product $product The product. * @param array $item The order item. * @param \WC_Order $order The order. * @return \WC_Product The filtered product */ function sv_wc_mpc_shipstation_get_product_from_item_weight($product, $item, $order) { if (WC_Price_Calculator_Product::pricing_calculated_weight_enabled($product)) { $settings = new WC_Price_Calculator_Settings($product); if ('weight' == $settings->get_calculator_type()) { // Now, the weight calculator products have to be handled specially // since the customer is actually supplying the weight, but it will // be in pricing units which may not be the same as the globally // configured WooCommerce Weight Unit expected by other plugins and code if (isset($item['item_meta']['_measurement_data'][0])) { $measurement_data = maybe_unserialize($item['item_meta']['_measurement_data'][0]); if (isset($measurement_data['_measurement_needed_unit']) && isset($measurement_data['_measurement_needed'])) { $supplied_weight = new WC_Price_Calculator_Measurement($measurement_data['_measurement_needed_unit'], $measurement_data['_measurement_needed']); // set the product weight as supplied by the customer, in WC Weight Units $product->weight = $supplied_weight->get_value(get_option('woocommerce_weight_unit')); } } } elseif ($product->get_weight()) { if (isset($item['item_meta']['_measurement_data'][0])) { $measurement_data = maybe_unserialize($item['item_meta']['_measurement_data'][0]); // record the configured weight per unit for future reference if (!isset($measurement_data['_weight'])) { $measurement_data['_weight'] = $product->get_weight(); } // calculate the product weight = unit weight * total measurement (both will be in the same pricing units so we have say lbs/sq. ft. * sq. ft. = lbs) $product->weight = $measurement_data['_weight'] * $measurement_data['_measurement_needed']; } } } return $product; }
/** * Pricing calculator calculated weight handling * * This method is responsible for the Pricing Calculator * products calculated weight handling. By default, a pricing calculator product's * weight will be defined as would any other, non-customizable product. Meaning * that if you have a weight of '10 lbs' for custom-sized tiling, an item could * be of any area and still weigh 10 lbs, which probably isn't very realistic. * * With calculated weight enabled, that same weight of '10' would repesent * '10 lbs / sq ft' meaning that the total weight of an item is calculated based * on its weight ratio and total measurement. * * The implementation strategy used to achieve this is to hook into some critical * actions in the WC_Cart class, loop through the cart items and calculate and * set a weight on the relevant products. Then when the various shipping * methods call the $product->get_weight() the correct, calculated weight will * be returned. * * @since 3.0 * @param WC_Cart $cart the cart object */ public function calculate_product_weights($cart) { // Loop through the cart items calculating the total weight for any pricing // calculator calculated weight products foreach ($cart->cart_contents as $cart_item_key => &$values) { $product = $_product = $values['data']; // need the parent product to retrieve the calculator settings from if (isset($_product->variation_id) && $_product->variation_id) { $product = wc_get_product($_product->id); } if (WC_Price_Calculator_Product::pricing_calculated_weight_enabled($_product)) { $settings = new WC_Price_Calculator_Settings($product); if ('weight' == $settings->get_calculator_type()) { // Now, the weight calculator products have to be handled specially // since the customer is actually supplying the weight, but it will // be in pricing units which may not be the same as the globally // configured WooCommerce Weight Unit expected by other plugins and code $supplied_weight = new WC_Price_Calculator_Measurement($values['pricing_item_meta_data']['_measurement_needed_unit'], $values['pricing_item_meta_data']['_measurement_needed']); // set the product weight as supplied by the customer, in WC Weight Units $_product->weight = $supplied_weight->get_value(get_option('woocommerce_weight_unit')); } elseif ($_product->get_weight()) { // record the configured weight per unit for future reference if (!isset($values['pricing_item_meta_data']['_weight'])) { $values['pricing_item_meta_data']['_weight'] = $_product->get_weight(); } // calculate the product weight = unit weight * total measurement (both will be in the same pricing units so we have say lbs/sq. ft. * sq. ft. = lbs) $_product->weight = $values['pricing_item_meta_data']['_weight'] * $values['pricing_item_meta_data']['_measurement_needed']; } } } }
/** * Append the dimension unit to the weight unit option value * * @since 3.7.00 * @param string $weight_unit The value of woocommerce_weight_unit option * @return string The weight per unit label */ public function add_weight_per_unit_label($weight_unit) { global $product; // bail if the calculator isn't enabled for this product if (!$product || !WC_Price_Calculator_Product::calculator_enabled($product)) { return; } // bail if the calculator isn't enabled for this product if (!WC_Price_Calculator_Product::pricing_calculated_weight_enabled($product)) { return; } $settings = new WC_Price_Calculator_Settings($product); return $weight_unit . ' / ' . $settings->get_pricing_unit(); }