None of my WooCommerce functions are working - php

Based on Go through certain WooCommerce orders, collect data and then send the results via email anwer code that is supposed to take all the WooComerce orders from yesterday total them and email them to me, but the email prints 0 for all the values.
<?php
define('WP_USE_THEMES', false);
require( dirname( __FILE__ ) . '/wp-load.php' );
// Date
$yesterday = date( 'Y-m-d', strtotime( ' -1 days ' ) );
// Args
$args = array(
'date_created' => $yesterday,
);
// Get WC orders
$orders = Wc()->wc_get_orders( $args );
// Initialize
$subtotal = 0;
$gratuity = 0;
$taxes = 0;
// NOT empty
if ( ! empty ( $orders ) ) {
foreach ( $orders as $order ) {
// DEBUG information, removed if desired
echo '<p>ID = ' . $order->get_id() . '</p>';
// Get subtotal
$subtotal += $order->get_subtotal();
// Get fees
foreach ( $order->get_fees() as $fee_id => $fee ) {
$gratuity += $fee['line_total'];
}
// Get tax
$taxes += $order->get_total_tax();
}
}
// Send e-mail
$to = 'jesse#munerismedia.com';
$subject = 'Order totals for yesterday';
$body = '<p>Subtotal = ' . $subtotal . '</p><p>Gratuity = ' . $gratuity . '</p><p>Taxes = ' . $taxes . '</p>';
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $body, $headers );
?>
I think I might be missing a dependency or something. Btw this is a nightly running cron job.

Related

My for loop in this code is capped at 10 any ideas why that might be? [duplicate]

This question already has answers here:
How to query Woocommerce orders on a page
(2 answers)
Closed 1 year ago.
So I have this code that takes woocommerce orders from yesterday and prints information about them in an email for some reason it is only going through my for loop a max of 10 times and i dont quite understand why any guidance would be fantastic.
<?php
define('WP_USE_THEMES', false);
require( dirname( __FILE__ ) . '/wp-load.php' );
// Date
date_default_timezone_set('PST');
$today = date( 'Y-m-d' );
// Args
$args = array(
'date_created' => $today,
);
// Get WC orders
$orders = \wc_get_orders( $args );
// Initialize
$subtotal = 0;
$gratuity = 0;
$taxes = 0;
// NOT empty
if ( ! empty ( $orders ) ) {
foreach ( $orders as $order ) {
echo $order->get_id();
// Get subtotal
$subtotal += $order->get_subtotal();
// Get fees
foreach ( $order->get_fees() as $fee_id => $fee ) {
$gratuity += $fee['line_total'];
}
// Get tax
$taxes += $order->get_total_tax();
}
}
$convenience = $gratuity;
$gratuity -= .04 * $subtotal;
echo 'Date = ' . $today . ' Subtotal = ' . $subtotal . ' Convenience Fee' . $convenience . ' Gratuity = ' . $gratuity . ' Taxes = ' . $taxes . '';
// Send e-mail
$to = 'jesse#munerismedia.com';
$subject = 'Order totals for today';
$body = '<p>Date = ' . $today . '</p><p>Subtotal = ' . $subtotal . '</p><p>Gratuity = ' . $gratuity . '</p><p>Taxes = ' . $taxes . '</p>';
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $body, $headers );
?>
From the documentation (emphasis mine):
limit
Accepts an integer: Maximum number of results to retrieve or -1 for unlimited.
Default: Site 'posts_per_page' setting.
So your posts_per_page setting is probably 10. To get them all, you need to add the limit option to your args array:
$args = array(
'limit' => -1,
'date_created' => $today,
);
$orders = wc_get_orders( $args );

Replace zero with FREE for WooCommerce shipping rates on single product page

Based on the answer on my previous question, Issue display shipping data on WooCommerce single product page, I'm trying to replace the 0 with FREE or whatever word I choose.
Problem is, whatever I do, it does not work. This is my attempt and I need help with it:
add_action('woocommerce_after_add_to_cart_form', 'display_shipping_on_product_page', 10, 0);
function display_shipping_on_product_page(){
// get all zones
$zones = WC_Shipping_Zones::get_zones();
// get the shop base country
$base_country = WC()->countries->get_base_country();
$base_city = WC()->countries->get_base_city();
// start display of table
echo '<div>' . __( '<b>Available Shipping</b>', 'woocommerce' );
echo '<br><small><span class="shipping-time-cutoff">All orders are shipped from the '.$base_country.'. Order before 12AM Mon-Fri for same day delivery within '.$base_city.'. Order before 3PM Mon-Thu for next day delivery.</span></small>';
echo '<small><table class="shipping-and-delivery-table">';
// get name of each zone and each shipping method for each zone
foreach ( $zones as $zone_id => $zone ) {
echo '<tr><td>';
echo '<strong>' . $zone['zone_name'] . '</strong>' . '</td><td>';
$zone_shipping_methods = $zone['shipping_methods'];
foreach ( $zone_shipping_methods as $index => $method ) {
$instance = $method->instance_settings;
if ( isset( $instance['min_amount'] ) ) {
$instance_min_amount = $instance['min_amount'];
} else {
$instance_min_amount = 0;
}
if ( isset( $instance['cost'] ) ) {
$instance_cost = $instance['cost'];
} else {
$instance_cost = str_replace($instance_cost, "FREE" );
}
$cost = $instance_cost ? $instance_cost : $instance_min_amount;
$above = $instance_min_amount ? 'above ' : '';
echo $instance['title'] . ': ' . $above . '<strong>' . wc_price( $cost ) . '</strong>' . '<br>';
}
echo '</td></tr>';
}
echo '</table></small></div>';
}
This is what I tried to add / edit without success:
$instance_cost = str_replace($instance_cost, "FREE" );
To display 'free' instead of 0, you need to change your if/else conditions. Explanation via comment tags added to my answer.
So you get:
function action_woocommerce_after_add_to_cart_form() {
// get all zones
$zones = WC_Shipping_Zones::get_zones();
// get the shop base country
$base_country = WC()->countries->get_base_country();
$base_city = WC()->countries->get_base_city();
// start display of table
echo '<div>' . __( 'Available Shipping', 'woocommerce' );
echo '<br><small><span class="shipping-time-cutoff">All orders are shipped from the '.$base_country.'. Order before 12AM Mon-Fri for same day delivery within '.$base_city.'. Order before 3PM Mon-Thu for next day delivery.</span></small>';
echo '<small><table class="shipping-and-delivery-table">';
// get name of each zone and each shipping method for each zone
foreach ( $zones as $zone_id => $zone ) {
echo '<tr><td>';
echo '<strong>' . $zone['zone_name'] . '</strong>' . '</td><td>';
$zone_shipping_methods = $zone['shipping_methods'];
foreach ( $zone_shipping_methods as $index => $method ) {
$instance = $method->instance_settings;
// Initialize
$above = '';
$output_cost = __( 'Free', 'woocommerce' );
// Cost isset
if ( isset( $instance['cost'] ) ) {
// NOT empty
if ( ! empty ( $instance['cost'] ) ) {
// Output
$output_cost = wc_price( $instance['cost'] );
}
}
// Min amount isset
if ( isset( $instance['min_amount'] ) ) {
// NOT empty
if ( ! empty ( $instance['min_amount'] ) ) {
// Above
$above = __( 'above ', 'woocommerce' );
// Output
$output_cost = wc_price( $instance['min_amount'] );
}
}
echo $instance['title'] . ': ' . $above . '<strong>' . $output_cost . '</strong>' . '<br>';
}
echo '</td></tr>';
}
echo '</table></small></div>';
}
add_action( 'woocommerce_after_add_to_cart_form', 'action_woocommerce_after_add_to_cart_form', 10, 0 );

Get all persons as a sum from all WooCommerce bookings

I use the official woocommerce booking plugin and I try do get the quantity of all persons that have booked a product.
for a single order that's no problem with:
if ( is_callable( 'WC_booking_Data_Store::get_booking_ids_from_order_id') ) {
$booking_data = new WC_booking_Data_Store();
$booking_ids = $booking_data->get_booking_ids_from_order_id( $order->get_id() );
}
foreach ( $booking_ids as $booking_id ) {
$booking = new WC_booking( $booking_id );
$person_count = array_sum( $booking->get_person_counts() );
$total_person_count .= 'Booking id: ' . $booking_id . ' Person Count: ' . $person_count . ' ';
}
but how can I collect the sum of all bookings? Hope you can help me
To get all "complete" bookings persons count use the following:
// get all bookings Ids with a status "complete"
$bookings_ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'wc_booking', // booking post type
'post_status' => 'complete',
'fields' => 'ids',
));
$persons_count = 0; // Initializing
$persons_html = '<table><tr><th>Booking id</th><th>Persons count</th></tr>'; // Initializing
// Loop through booking Ids
foreach ( $bookings_ids as $booking_id ) {
$booking = new WC_Booking( $booking_id ); // Get the WC_Booking instance object
$count = array_sum( $booking->get_person_counts() );
$persons_count += $count;
$persons_html .= '<tr><td>' . $booking_id . '</td><td>' . $count . '</td></tr>';
}
$persons_html .= '<tr><th><strong>Total count</th><td style="color:red">' . $persons_count . '</td></tr>';
// Output
echo $persons_html . '</table>';
Tested and works.
To make it lighter, you could replace:
$booking = new WC_Booking( $booking_id ); // Get the WC_Booking instance object
$count = array_sum( $booking->get_person_counts() );
simply by:
$count = array_sum( get_post_meta($booking_id, '_booking_persons', true) );
following your updated code, please try this
<?php
if ( is_callable( 'WC_booking_Data_Store::get_booking_ids_from_order_id') ) {
$booking_data = new WC_booking_Data_Store();
$booking_ids = $booking_data->get_booking_ids_from_order_id( $order->get_id() );
}
$total_count_data = array();
$total_count_persons = 0;
foreach ( $booking_ids as $booking_id ) {
$booking = new WC_booking( $booking_id );
$person_count = array_sum( $booking->get_person_counts() );
$total_count_persons+= $person_count;
$total_count_data[] = array(
'Booking' => $booking_id,
'Person' => $person_count
);
}

Getting a value from a function in WordPress

I am a bit new to WordPress and i have a small problem.
I'm checking if my mail was send or not and i want to save this information in a custom table that i made. I need to retrieve this information in a different function where I then save this in my custom table.
This is the function where i check if the mail is send or not.
/*
* Send notification when stock is low
*/
function boilerplate_custom_low_stock_notification( $order ) {
foreach ( $order->get_items() as $item ) {
print_r($item);
if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->managing_stock() ) {
$new_stock = get_post_meta( $product->get_id(), '_stock', true );
$minimum_stock = get_post_meta( $product->get_id(), '_stock_minimum', true );
$stock = $product->get_stock_quantity();
$name = $product->get_name();
if ( $new_stock <= $minimum_stock ) {
//Send email to admin
$notification = wp_insert_post(
array(
'post_type' => 'shop_history',
'post_title' => 'The stock of '. $name . ' is running low.',
'post_content' => 'The stock is running low. There are only ' . $stock . " pieces left.",
'post_status' => 'publish',
) );
$mailResult = false;
$mailResult = wp_mail( get_option('admin_email'), 'Your stock is running low', 'The stock of ' . $name . ' is running low. You have ' . $stock . ' piece(s) left.' );
if( $mailResult == true){
$mail_send = "Mail was send";
}else{
$mail_send = "Something went wrong en there was no mail send";
}
//error_log( $mail_send );
return $notification;
}
}
}
}
add_action( 'woocommerce_reduce_order_stock', 'boilerplate_custom_low_stock_notification', 10, 3 );
In this function i want to save the information.
/*
* Add values to column
*/
function woocommerce_shop_history_mail_column( $column, $post_id ) {
switch ( $column ) {
case 'mail' :
echo 'Is my mail send or not?';
break;
}
}
add_filter( 'manage_shop_history_posts_custom_column', 'woocommerce_shop_history_mail_column', 10, 2 );

Display specific booking data below cart item name in Woocommerce Bookings

I'm using Woocommerce and Woocommerce Bookings for a villa booking website and I have a small issue I can't fix.
I'd like to add a field "Details" into my cart (Cart Details). This field will display the duration of the booking and also the price / night of each villa.
My villas have some resources with a specific block cost.
Regarding the duration value, I can display it by using this code bellow :
<?php
/*display_card_data();*/
$items = WC()->cart->get_cart();
foreach($items as $item) {
$duration = $item['booking']['duration'];
}
// displaying values for test
echo $duration. ' x Night Price' .$price ;
?>
I'm wondering how I can display the block cost in this field.
Please any help will be useful.
This can be done with the following code (but they can be many unit prices in WC Bookings):
add_filter( 'woocommerce_cart_item_name', 'booking_details_after_name', 30, 3 );
function booking_details_after_name( $product_name, $cart_item, $cart_item_key ) {
if ( isset( $cart_item['booking']['duration'] ) ){
// Duration
$duration = $cart_item['booking']['duration'];
// Price cost ( they can be many different )
$base_cost = get_post_meta( $cart_item['product_id'], '_wc_booking_cost', true );
$block_cost = get_post_meta( $cart_item['product_id'], '_wc_booking_block_cost', true );
// Output
$product_name .= '<br><span class="booking-details">';
$product_name .= $duration . __(" x Night Price ", "woocommerce") . wc_price($base_cost);
$product_name .= '</span>';
}
return $product_name;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
Specific Update:
add_filter( 'woocommerce_cart_item_name', 'booking_details_after_name', 30, 3 );
function booking_details_after_name( $product_name, $cart_item, $cart_item_key ) {
if ( isset( $cart_item['booking']['duration'] ) ){
// Duration
$duration = (int) $cart_item['booking']['_duration'];
$resource_id = $cart_item['booking']['_resource_id'];
$start_time = $cart_item['booking']['_start_date'];
$end_time = $cart_item['booking']['_end_date'];
$loop_time = (int) $start_time;
$day = 86400; // In seconds
// Price cost ( they can be many different )
$res_block_cost = get_post_meta( $cart_item['product_id'], '_resource_block_costs', true );
$booking_pricing = get_post_meta( $cart_item['product_id'], '_wc_booking_pricing', true );
foreach ( $res_block_cost as $key => $value ){
if( $key == $resource_id ){
$bloc_cost = $value;
break;
}
}
$cost = array();
foreach ( $booking_pricing as $key => $value ){
$from = strtotime($value['from']);
$to = strtotime($value['to']) + 86399;
for( $i = 0; $i < $duration; $i++ ){
if( $loop_time >= $from && $loop_time <= $to ){
$cost[] = $value['cost'];
$loop_time += $day;
}
}
}
$cost = array_sum( $cost ) / $duration;
// Output
$product_name .= '<br><span class="booking-details">';
$product_name .= $duration . __(" x Night Price ", "woocommerce") . wc_price($bloc_cost + $cost);
$product_name .= '</span>';
}
return $product_name;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.

Categories