/** * 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; }
/** * 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; }
/** * 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(); }
/** * Add a measurement product to the cart. This allows for the programmatic * addition of measurement pricing calculator products to the cart. * * This method expects the single total measurement needed, given by * $measurement_needed, this would be the dimension, area, volume or weight * depending on the type of calculator. * * This method also expects the full set of product measurements, given by * $measurements. For calculators with a single measurement like the dimension * calculator or simple area, this will contain the same value as * $measurement_needed. For more complex calculators, like Area (w x l) * this is how the width and length measurements are specified. For * convenience use <code>WC_Price_Calculator_Product::get_product_measurements( $product )</code> * to get the set of dimensions for your product, along with the correct * units, and set whatever values you need. * * @since 3.0 * @param string $product_id contains the id of the product to add to the cart * @param WC_Price_Calculator_Measurement $measurement_needed the total * measurement desired, ie 1 m, 3 sq. ft., etc * @param array $measurements array of WC_Price_Calculator_Measurement product * measurements, ie 1 m or 1.5 ft, 1.5 ft. Defaults to $measurement_needed * for convenience for calculators with a single measurement like dimension, * simple area, etc. * @param string $quantity contains the quantity of the item to add * @param int $variation_id optional variation id * @param array $variation optional attribute values * @param array $cart_item_data optional extra cart item data we want to pass into the item * @return bool true on success */ public function add_to_cart($product_id, $measurement_needed, $measurements = array(), $quantity = 1, $variation_id = '', $variation = '', $cart_item_data = array()) { // if measurements is empty just use the provided $measurement_needed (this is a shortcut for calculators with only one measurement, ie 'length', 'area', etc) if (empty($measurements)) { $measurements[] = $measurement_needed; } // build up the cart item data with the required values that would normally come in over the add to cart post request $cart_item_data['pricing_item_meta_data']['_measurement_needed_internal'] = $measurement_needed->get_value(); $cart_item_data['pricing_item_meta_data']['_measurement_needed_unit_internal'] = $measurement_needed->get_unit(); $cart_item_data['pricing_item_meta_data']['_quantity'] = $quantity; $product = wc_get_product($product_id); $settings = new WC_Price_Calculator_Settings($product); if (WC_Price_Calculator_Product::pricing_calculator_inventory_enabled($product)) { // pricing calculator product with inventory enabled, means we need to take the item quantity (ie 2) and determine the unit quantity (ie 2 * 3 ft = 6) $quantity *= $measurement_needed->get_value($settings->get_pricing_unit()); } foreach ($measurements as $measurement) { $cart_item_data['pricing_item_meta_data'][$measurement->get_name()] = $measurement->get_value(); } // initialize the cart_contents member if needed to avoid a warning from cart::find_product_in_cart() if (is_null(WC()->cart->cart_contents)) { WC()->cart->cart_contents = array(); } return WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation, $cart_item_data); }
/** * Manage the order stock (whether restore or reduce) from the order admin * returning the true product stock change if this is for a pricing calculator * product/item with inventory enabled. Ie 2 pieces of cloth at 3 ft each * we'd want to return 6 * * @since 3.0 * @param numeric $quantity the new quantity * @param string $item_id the order item identifier * @return numeric $quantity the measurement quantity */ public function admin_manage_order_stock($quantity, $item_id) { $order_id = absint($_POST['order_id']); $order = wc_get_order($order_id); $order_items = $order->get_items(); $product = wc_get_product($order_items[$item_id]['product_id']); if (WC_Price_Calculator_Product::pricing_calculator_inventory_enabled($product) && isset($order_items[$item_id]['measurement_data'])) { $settings = new WC_Price_Calculator_Settings($product); $measurement_data = maybe_unserialize($order_items[$item_id]['measurement_data']); $total_amount = new WC_Price_Calculator_Measurement($measurement_data['_measurement_needed_unit'], $measurement_data['_measurement_needed']); // this is a pricing calculator product so we want to return the // quantity in terms of units, ie 2 pieces of cloth at 3 ft each = 6 $quantity *= $total_amount->get_value($settings->get_pricing_unit()); } return $quantity; }