/** * Calculate the item price based on the given measurements * * @since 3.1.3 * @param WC_Product $product the product * @param float $measurement_needed_value the total measurement needed * @param string $measurement_needed_value_unit the unit of $measurement_needed_value * @param bool $round Optional. If true the returned price will be rounded to two decimal places. Default true. * @return float the calculated price */ public static function calculate_price($product, $measurement_needed_value, $measurement_needed_value_unit, $round = true) { $price = $product->get_price(); // get the parent product if there is one $_product = 'WC_Product_Variation' == get_class($product) ? $product->parent : $product; if (self::pricing_calculator_enabled($_product)) { $settings = new WC_Price_Calculator_Settings($_product); $measurement_needed = new WC_Price_Calculator_Measurement($measurement_needed_value_unit, (double) $measurement_needed_value); // if this calculator uses pricing rules, retrieve the price based on the product measurements if ($settings->pricing_rules_enabled()) { $product->price = $settings->get_pricing_rules_price($measurement_needed); } // calculate the price $price = $product->get_price() * $measurement_needed->get_value($settings->get_pricing_unit()); // is there a minimum price to use? if ($product->wc_measurement_price_calculator_min_price > $price) { $price = $product->wc_measurement_price_calculator_min_price; } } if ($round) { $price = round($price, absint(get_option('woocommerce_price_num_decimals', 2))); } // return the final price return $price; }
/** * Calculate the item price based on the given measurements * * @since 3.1.3 * @param WC_Product $product the product * @param float $measurement_needed_value the total measurement needed * @param string $measurement_needed_value_unit the unit of $measurement_needed_value * @return float the calculated price */ public static function calculate_price($product, $measurement_needed_value, $measurement_needed_value_unit) { $price = $product->get_price(); // get the parent product if there is one $_product = 'WC_Product_Variation' == get_class($product) ? $product->parent : $product; if (self::pricing_calculator_enabled($_product)) { $settings = new WC_Price_Calculator_Settings($_product); $measurement_needed = new WC_Price_Calculator_Measurement($measurement_needed_value_unit, (double) $measurement_needed_value); // if this calculator uses pricing rules, retrieve the price based on the product measurements if ($settings->pricing_rules_enabled()) { $product->price = $settings->get_pricing_rules_price($measurement_needed); } // calculate the price $price = $product->get_price() * $measurement_needed->get_value($settings->get_pricing_unit()); // is there a minimum price to use? if (WC_Price_Calculator_Product::get_product_meta($product, 'wc_measurement_price_calculator_min_price') > $price) { $price = WC_Price_Calculator_Product::get_product_meta($product, 'wc_measurement_price_calculator_min_price'); } } // return the final price return $price; }
/** * Returns the cart item data for the given item being re-ordered. This is * a somewhat complex process of re-configuring the product based on the * original measurements, taking into account unit changes. We do not handle * calculator type changes at the moment; in fact there's probably no way * of accounting for this. (actually we could handle calculator changes as * long as the calculator type was simplified, ie Area (L x W) -> Area, * but aside from that there's nothing we can do) * * @since 3.0 * @param array $cart_item_data the cart item data * @param array $item the item * @param WC_Order $order the original order * @return array the cart item data */ public function order_again_cart_item_data($cart_item_data, $item, $order) { $product = wc_get_product($item['product_id']); if (WC_Price_Calculator_Product::pricing_calculator_enabled($product) && isset($item['item_meta']['_measurement_data'][0]) && $item['item_meta']['_measurement_data'][0]) { $measurement_data = maybe_unserialize($item['item_meta']['_measurement_data'][0]); $settings = new WC_Price_Calculator_Settings($product); $measurements = $settings->get_calculator_measurements(); // get the old product measurements, converting to the new measurement units as needed foreach ($measurements as $measurement) { if (isset($measurement_data[$measurement->get_name()])) { $current_unit = $measurement->get_unit(); $measurement->set_value($measurement_data[$measurement->get_name()]['value']); $measurement->set_unit($measurement_data[$measurement->get_name()]['unit']); $cart_item_data['pricing_item_meta_data'][$measurement->get_name()] = $measurement->get_value($current_unit); } } // the product total measurement $measurement_needed = new WC_Price_Calculator_Measurement($measurement_data['_measurement_needed_unit'], $measurement_data['_measurement_needed']); // if this calculator uses pricing rules, retrieve the price based on the product measurements if ($settings->pricing_rules_enabled()) { $product->price = $settings->get_pricing_rules_price($measurement_needed); } // calculate the price $price = $product->get_price() * $measurement_needed->get_value($settings->get_pricing_unit()); // is there a minimum price to use? if ($product->wc_measurement_price_calculator_min_price > $price) { $price = $product->wc_measurement_price_calculator_min_price; } // set the product price based on the price per unit and the total measurement $cart_item_data['pricing_item_meta_data']['_price'] = $price; // save the total measurement (length, area, volume, etc) in pricing units $cart_item_data['pricing_item_meta_data']['_measurement_needed'] = $measurement_needed->get_value(); $cart_item_data['pricing_item_meta_data']['_measurement_needed_unit'] = $measurement_needed->get_unit(); // pick up the item quantity which we set in order_again_item_set_quantity() if (isset($item['item_meta']['_quantity'][0])) { $cart_item_data['pricing_item_meta_data']['_quantity'] = $item['item_meta']['_quantity'][0]; } } return $cart_item_data; }