I currently have a form where the admin can bulk update sale prices of products within one screen.
When the form is submitted i simply use update_post_meta like this:
update_post_meta($id,'_sale_price', 'new sale price here');
This updates the _sale_price meta key. When i go into the admin to check this, the new sale price has been inserted. When i view the product on the front end, the item is not marked as on sale. I have to go back in and re-save the product.
My question is, does woocommerce add some other meta_key to mark the product as on sale? I have had a dig round in the database for all the custom fields inserted, but can only see _sale_price.
Any help would be greatly appreciated
Having a look at the Product abstract class in WooCommerce the following php code gets whether or not the product is on sale:
return ( $this->sale_price != $this->regular_price && $this->sale_price == $this->price );
Which seems to indicate that the _price has to be the same as the sale_price in order for it to be classed as on sale. So just
update_post_meta($id, '_price', 'new sale price here too');
as well as the code in your question and it should work.
Related
A particular coupon settings assume a coupon instance auto-generation if a customer purchases a certain product. Actually a new coupon instance was generated as a purchase result. I tried to get that coupon instance object, but got an initial coupon instance which was designed as a template for new coupons auto-generation.
a code snippet I used
$coupon_titles = get_post_meta( $download['product_id'], '_coupon_title', true );
for($i=0; $i<count($coupons); $i++ ){
if($coupons[$i]->post_title == $coupon_titles[0]){
$theCoupon = $coupons[$i];
}
}
When I tried to use $coupon_titles[1] array element in assumption that the first index is for the coupon template, I've got an error stating the absence of such the array element. Appreciate for any clue.
Before I get too far down this rabbit hole...
I have a product in a category that is essentially a selection of 4 other products. It can be any combination of select products. Pricing is based off of regular price for those products.
What I've managed so far
Controlled through normal WooCommerce attributes interface. Admin puts in an attribute use-for-custom with the value being the category of item, i.e. cupcakes
The result is an association to a product slugged custom-assortment in the cupcakes category. This product will be an option for any/all of the 4 selections in the custom-assortment product in cupcakes category.
I also have a function in functions.php that queries all products with this set attribute and builds a neat little array of id/title/cost. I managed that via this post earlier, plus
$useable = array();
foreach ($products as $product){
$useable[] = array(
'id' => $product->ID,
'name' => $product->post_title,
'desc' => $product->post_excerpt,
'cost' => floatval(wc_get_product($product->ID)->get_price())/4
//cost is 1/4 as 4 will be selected to create 1 new product
);
}
Notes
It does not need to actually relate the selection back to a particular product. Having the selected product name(s) shown in the final order is enough for the admin. However, it would be nice to keep that reference as it may lead to additional functionality later.
Not concerned with stock at the moment, or any other attributes from the selected products except price.
Thoughts
I've tried a little to get custom variations to create programmatically via this post from LoicTheAztec, but so far I haven't gotten them to show up. I might be able to with a little more poking as his stuff is usually spot-on.
foreach ($useable as $useit){
$display = $useit['name'] . " (" . $useit['cost'] . ")";
$variation_data = array(
'attributes' => array(
'flavor-one' => $display,
'flavor-two' => $display,
'flavor-three' => $display,
'flavor-four' => $display
),
'sku' => '',
'regular_price' => $useit['cost'],
'sale_price' => ''
);
var_dump($product->get_id());
create_product_variation($product->get_id(), $variation_data);
}
Alternatively, I could probably create the drop-down selections manually and run a filter on the price based on selections. That seems like a lot of manual recreation of functionality though - checking validity, pricing, etc.
Final question
Is there a way to use one product as a variable product attribute for another product already? It doesn't seem like something far-fetched, but I haven't been able to google-foo anything. My google-foo has not been great recently.
Assuming a single product that can be any combination of 4 of 10 other products, using variations means 10,000 possible products added. That seems unreasonable, so I went with the option of doing this another way.
Will expand this answer with code shortly, but basically:
Query posts to get product type posts with the custom attribute grouping it with this configurable option. Output these as select elements with options of items in the add-to-cart form. Option values as product IDs and displayed as product name + price for that option.
Hook to the add to cart action to check options (passed in the $_POST) and store them as attributes on the cart item.
Hook to the cart pricing filter and use the cart item attributes to calculate final product price based on the assortment products' original prices.
Also:
add attribute display to the cart
add front-end control to display changing price with the changing attributes
I want to remove/exclude any orders with the order status "On Hold" from woocommerce sales reports. By default On hold orders are included in the sales reports.
There is a function "exclude_from_order_sales_reports" found here - https://docs.woothemes.com/wc-apidocs/function-wc_register_order_type.html - that will exclude a post type from sales reports.
Also the woo order types and order status are handled here - https://docs.woothemes.com/wc-apidocs/source-function-wc_register_order_type.html#167-221
Unfortunately my php coding is basic (im still learning) and i have no clue where to start with all this code. How can I use the above function to remove on hold order from sales reports?
i seen on woocommerce main report class WC_Admin_Report on line 67 they have filter like this $order_status = apply_filters( 'woocommerce_reports_order_statuses', $order_status );
so i think you can easily alter the default order status for reports by adding filter like this on your functions.php
add_filter( 'woocommerce_reports_order_statuses', 'my_custom_order_status_for_reports', 10, 1 );
function my_custom_order_status_for_reports($order_statuses){
$order_statuses = array('completed'); // your order statuses for reports
return $order_statuses;
}
I am using woocommerce plugin v2.2.8 for my eCommerce site. I am using weight based shipping method. Is there is any possibility to add shipping cost with products actual price which is displaying in product page?
For Eg.. Product1 = Rs 800/- & shipping cost of this product is Rs 50/-
Product1 price in shop page should be displayed as Rs 850/- (Actual price + shipping cost) Note: shipping cost calculated from weight based shipping method. Is this possible?
Any idea regarding this???
Shipping always needs a destination address, but when you are showing a product in shop page then no address is available there. But, as you can have a flat rate shipping setting for every zone then you can retrieve that value by your own and add that price to product. If you need product based shipping price, define shipping classes, assign desired shipping class to product and configure prices for each shipping class.
Now while showing price for product in front end you can use following woocommerce hook and put your logic to modify the price.
function return_custom_price($price, $product) {
//Apply your logic and modify the price
return $price;
}
add_filter('woocommerce_get_price', 'return_custom_price', 10, 2);
Here is your cart Data
global $woocommerce;<br>
$data = $woocommerce->cart->get_cart();<br><br>
<br>
$product_id = array();<br>
$product_weigth = array();<br>
$weight_total = 0;<br>
<br>
Break your cart Data
foreach($data as $value)<br>
{<br>
$product_id[] = $value['product_id'];<br>
}<br>
<br>
for($i=0;$i < count($product_id);$i++)<br>
{<br>
$product_weigth[] = get_post_meta($product_id[$i],'_weight',true);<br>
$weight_total += get_post_meta($product_id[$i],'_weight',true);<br>
}<br><br>
<br>
Print Your Cart Products ID
print_r($product_id);<br><br>
Print Your Cart Products Weight
print_r($product_weigth);<br><br>
Total Weight
echo $weight_total;<br><br>
Add Fee
$woocommerce->cart->add_fee('Shipping Charges(Weight)'.$weight_total, $your_fee, true, 'standard' );<br><br>
Now ou can set your fee by weight.. if - else conditions
I'm building a site with Wordpress and WooCommerce for someone for the purposes of a business, but they have certain items that cannot be sold together - essentially the opposite of a force sell or chained products. If a customer puts product A in their cart, I don't want them to be able to put product C in with it, but B and D are fine. Alternatively, when it goes to checkout, separating the products into two separate orders would work as well. Is there any way to do this? This is my first time using Wordpress, so I'm a bit at a loss.
You can use this code below :
add_action('woocommerce_add_to_cart_handler','mycustomfuncion',11,2);
function mycustomfuncion($p,$q)
{
global $woocommerce;
$cartItem = $woocommerce->cart->cart_contents;
$currentProductId = $q->id;
foreach($cartItem as $item)
{
$productItemId = $item['product_id'];
///your condition will be here
}
return $q;
}
You will get all product ids which are in cart by the $productItemId. And you will get current product id (which user wants to add to cart ) by $currentProductId. After your conditions if you want to allow to add to cart the product then return $q from the function otherwise don't return any value.