I create a custom shipping method.
(https://docs.woocommerce.com/document/shipping-method-api/)
In the calculate_shipping function i want to set the price of my shipping method based on the shipping zone:
If shipping zone is 'Zone 1' set price to 15
else set price to 20
So i want to know, how can i get the current shipping zone ?
I already try to see this doc: https://docs.woocommerce.com/wc-apidocs/class-WC_Shipping_Zone.html
Maybe i don't understand...
public function calculate_shipping( $package=Array()) {
global $woocommerce;
$cart_total=$woocommerce->cart->cart_contents_total;
$current_hour=date('His');
$start_hour='110000';
$end_hour='210000';
// CONDITIONAL CHECK
// OPEN HOUR
if($current_hour >= $start_hour && $current_hour <= $end_hour){
$is_open=true;
}else{
$is_open=false;
}
// price PER ZONE
$zone=""; // need to know how to get zone name or zone id
if($zone=='Zone 1' && $cart_total>='60'){
$min_order=true;
$cost = 6;
}elseif($zone=='Zone 2' && $cart_total>='120'){
$min_order=true;
$cost = 8;
}elseif($zone=='Zone 3' && $cart_total>='180'){
$min_order=true;
$cost = 9;
}else{
$min_order=false;
$cost = 0;
}
if($is_open==true && $min_order==true){
$allowed=true;
}else{
$allowed=false;
}
$rate = array(
'id' => $this->id,
'label' => 'Livraison Express T '.wc_get_shipping_zone().' T',
'cost' => $cost,
);
// Register the rate
if($allowed==true){
$this->add_rate( $rate );
}
}
I find a solution myself
Like that:
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
$zone=$shipping_zone->get_zone_name();
Complete function:
public function calculate_shipping( $package=Array()) {
global $woocommerce;
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
$zone=$shipping_zone->get_zone_name();
if($zone=='Zone 1'){
$cost = 6;
}else{
$cost=12;
}
$rate = array(
'id' => $this->id,
'label' => 'Delivery Name',
'cost' => $cost,
);
$this->add_rate( $rate );
}
Related
I need to hide WooCommerce shipping zone_id=1 & shipping zone_id=3 on Sundays.
I've stumbled upon this answer, and come up with this code:
// Hide $15 & $25 shipping rates on Sunday
add_filter('woocommerce_package_rates', 'amano_hide_shipping_method_on_sunday', 10, 2);
function amano_hide_shipping_method_on_sunday($available_shipping_methods, $package) {
$date = date("1");
$is_sunday = date('l', $date) == 'Sunday';
if($is_sunday) {
$hide_when_shipping_class_exist = array(
42 => array(
'free_shipping'
)
);
$hide_when_shipping_class_not_exist = array(
42 => array(
'wf_shipping_ups:03',
'wf_shipping_ups:02',
'wf_shipping_ups:01'
),
43 => array(
'free_shipping'
)
);
$shipping_class_in_cart = array();
foreach(WC()->cart->cart_contents as $key => $values) {
$shipping_class_in_cart[] = $values['data']->get_shipping_class_id();
}
foreach($hide_when_shipping_class_exist as $class_id => $methods) {
if(in_array($class_id, $shipping_class_in_cart)){
foreach($methods as & $current_method) {
unset($available_shipping_methods[$current_method]);
}
}
}
foreach($hide_when_shipping_class_not_exist as $class_id => $methods) {
if(!in_array($class_id, $shipping_class_in_cart)){
foreach($methods as & $current_method) {
unset($available_shipping_methods[$current_method]);
}
}
}
return $available_shipping_methods;
}
}
However, the bit I don't know how to customize is:
$hide_when_shipping_class_exist = array(
42 => array(
'free_shipping'
)
);
$hide_when_shipping_class_not_exist = array(
42 => array(
'wf_shipping_ups:03',
'wf_shipping_ups:02',
'wf_shipping_ups:01'
),
43 => array(
'free_shipping'
)
);
I don’t have any Shipping Classes, and don’t understand what they are. More code will probably need to be replaced to substitute hiding shipping classes for shipping zones, but I don't know what that code is.
Help appreciated please.
Code contains
On a specific day
Unset $rates[$rate_key] for certain zone IDs
Comment with explanation added to the code
function filter_woocommerce_package_rates( $rates, $package ) {
/* SETTINGS */
// Zone ID's
$hide_zones = array ( 1, 3 );
$on_day = 'Sunday';
/* END SETTINGS */
// Shipping zone
$shipping_zone = wc_get_shipping_zone( $package );
// Get zone ID
$zone_id = $shipping_zone->get_id();
// set the default timezone to use. Available since PHP 5.1
date_default_timezone_set('UTC');
// l - A full textual representation of the day of the week
$day_of_the_week = date( 'l' );
// True
if( $day_of_the_week == $on_day ) {
// In array
if ( in_array( $zone_id, $hide_zones ) ) {
// Loop
foreach ( $rates as $rate_key => $rate ) {
// Unset
unset( $rates[$rate_key] );
}
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
I have created a custom action button "Request Refund" on orders page of my-account in WooCommerce. I was looking, is there any way to hide this button after 14-days since order gets completed.
I have searched a lot, but no similar solution. Any help will be appreciated.
Here is my code:
function add_request_refund($actions, $order)
{
if ($order->has_status('completed'))
{
$actions['refund_request'] = array(
'url' => url_of_request_refund($order),
'name' => __('Request Refund', 'my-textdomain'),
);
}
return $actions;
}
add_filter('woocommerce_my_account_my_orders_actions', 'add_request_refund', 100, 2);
function url_of_request_refund($order)
{
$page_id = 4007;
$refund_url = trailingslashit(get_page_link($page_id)) . '?order=' . $order->get_order_number();
return $refund_url;
}
If you want to hide the button after 14 days from the order date then
you can just add a small check to your if block and that will do.
Here is the sample code:
function add_request_refund($actions, $order)
{
$order_date = date_create($order->get_date_created()->date('Y-m-d'));
$current_date = date_create(date('Y-m-d'));
$diff = date_diff($order_date, $current_date);
//print_r($diff);
if ($order->has_status('completed') && ($diff->days <= 14)) //check this line
{
$actions['refund_request'] = array(
'url' => url_of_request_refund( $order ),
'name' => __('Request Refund', 'my-textdomain'),
);
}
return $actions;
}
add_filter('woocommerce_my_account_my_orders_actions', 'add_request_refund', 100, 2);
Reference: date_diff()
function add_request_refund( $actions, $order ) {
$order_date = $order->order_date;
$getTodayDate = date('m/d/Y');
$date1 = date_create($order_date);
$date2 = date_create($getTodayDate);
//difference between two dates
$diff = date_diff($date2,$date1);
if ( $order->has_status( 'completed' ) && $diff->days < 15 ) {
$actions['refund_request'] = array(
'url' => url_of_request_refund( $order ),
'name' => __( 'Request Refund', 'my-textdomain' ),
);
}
return $actions;
}
add_filter( 'woocommerce_my_account_my_orders_actions', 'add_request_refund', 100, 2 );
function url_of_request_refund( $order ) {
$page_id = 4007;
$refund_url = trailingslashit( get_page_link( $page_id ) ) . '?order=' . $order->get_order_number();
return $refund_url;
}
This should work. Tested at my side!
I want to display the cost of the product after a discount coupon on the invoice.
I have the following code, but it displays only base price, not the cost after coupon code:
add_filter( 'wpo_wcpdf_woocommerce_totals', 'wpo_wcpdf_woocommerce_totals_custom', 10, 2 );
function wpo_wcpdf_woocommerce_totals_custom( $totals, $order ) {
$totals = array(
'subtotal' => array(
'label' => __('Subtotal', 'wpo_wcpdf'),
'value' => $order->get_subtotal_to_display(),
),
);
return $totals;
}
I tred to change $totals to $discount, but it didn't work.
Your actual code is just removing all totals, displaying the subtotal only. Please try the following hooked function, that will display the discounted subtotal after the discount amount:
add_filter( 'wpo_wcpdf_woocommerce_totals', 'add_discounted_subtotal_to_pdf_invoices', 10, 2 );
function add_discounted_subtotal_to_pdf_invoices( $totals, $order ) {
// Get 'subtotal' raw amount value
$subtotal = strip_tags($totals['cart_subtotal']['value']);
$subtotal = (float) preg_replace('/[^0-9.]+/', '', $subtotal);
// Get 'discount' raw amount value
$discount = strip_tags($totals['discount']['value']);
$discount = (float) preg_replace('/[^0-9.]+/', '', $discount);
$new_totals = array();
// Loop through totals lines
foreach( $totals as $key => $values ){
$new_totals[$key] = $totals[$key];
// Inset new calculated 'Subtotal discounted' after total discount
if( $key == 'discount' && $discount != 0 && !empty($discount) ){
$new_totals['subtotal_discounted'] = array(
'label' => __('Subtotal discounted', 'wpo_wcpdf'),
'value' => wc_price($subtotal - $discount)
);
}
}
return $new_totals;
}
Code goes in function.php file of your active child theme (or theme).
Tested and works. It should work for you too.
I have custom shipping method to add calculate the shipping, and using the below code
public function calculate_shipping( $package ) {
$postcode_data = $package['destination']['postcode'];
if(!empty($postcode_data)){
$weight = 0;
$zone_data = checkzone($postcode_data);
if(isset($package['destination']['postcode'])){
if(!empty($zone_data)){
$weight = WC()->cart->cart_contents_weight; // get cart total weight
if($weight <= 100){
$weight_range = ceil($weight / 10 );
}
elseif(($weight > 100 ) && ($weight < 150) ){
$weight_range = 11 ;
}
if($weight >= 150)
{
$weight_range = 12 ;
}
$pricing = getpricing($zone_data , $weight_range);
if($pricing > 0){
$rate = array(
'id' => $this->id,
'label' => 'Delivery',
'cost' => $pricing,
'calc_tax' => 'per_order'
);
// Register the rate
$this->add_rate( $rate );
wc_clear_notices();
}
} // if zone data
}
}
else {
$rate = array(
'id' => $this->id,
'label' => 'Delivery',
'cost' => 0,
'calc_tax' => 'per_order'
);
// Register the rate
$this->add_rate( $rate );
//wc_clear_notices();
//wc_add_notice( 'Please enter zipcode to calculate the shipping', 'error' );
}
} // calculate shipping
But at front end it's adding tax amount exclusive the tax. For the products tax is working fine but for the shipping is exclusive the price, I want inclusive of the shipping price for the tax.
I've been endlessly trying to add a shipping method to the following code but with no luck. Could a good samaritan please offer some assistance.
I just need to add a shipping method.
Basically what the code does is add the fields to the shipping zones section in woo commerce setting | Shipping Zones.
I'd like to add a [flat rate to the zone that is created]
I've searched everywhere but with no luck. :-(
<?php
//Creating the Zone.
function DW_shipping_zone_init() {
// Getting the Shipping object
$available_zones = WC_Shipping_Zones::get_zones();
// Get all WC Countries
$all_countries = WC()->countries->get_countries();
//Array to store available names
$available_zones_names = array();
// Add each existing zone name into our array
foreach ($available_zones as $zone ) {
if( !in_array( $zone['zone_name'], $available_zones_names ) ) {
$available_zones_names[] = $zone['zone_name'];
}
}
// Check if our zone 'C' is already there
if( ! in_array( 'C', $available_zones_names ) ){
// Create an empty object
$zone_za = new stdClass();
//Add null attributes
$zone_za->zone_id = null;
$zone_za->zone_order =null;
// Add shipping zone name
$zone_za->zone_name = 'C';
// Instantiate a new shipping zone with our object
$new_zone_za = new WC_Shipping_Zone( $zone_za );
// Add South Africa as location
$new_zone_za->add_location( 'ZA', 'country' );
// Save the zone, if non existent it will create a new zone
$new_zone_za->save();
// Add our shipping method to that zone
$new_zone_za->add_shipping_method( 'some_shipping_method' );
}
add_action( 'init', 'DW_shipping_zone_init' );
You can create plugin for this:
Create one folder inside wp-content/pluigins/ with name "woocommerce-fast-delivery-system"
Inside "woocommerce-fast-delivery-system" folder, create two files as displayed below:
1. fast-delivery-shipping-method.php
<?php
/*
Plugin Name: WooCommerce Fast Delivery Shipping Method
*/
/**
* Check if WooCommerce is active
*/
$active_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) );
if ( in_array( 'woocommerce/woocommerce.php', $active_plugins) ) {
add_filter( 'woocommerce_shipping_methods', 'add_fast_delivery_shipping_method' );
function add_fast_delivery_shipping_method( $methods ) {
$methods[] = 'WC_Fast_Delivery_Shipping_Method';
return $methods;
}
add_action( 'woocommerce_shipping_init', 'fast_delivery_shipping_method_init' );
function fast_delivery_shipping_method_init(){
require_once 'class-fast-delivery-shipping-method.php';
}
}
2. class-fast-delivery-shipping-method.php
<?php
class WC_Fast_Delivery_Shipping_Method extends WC_Shipping_Method{
public function __construct(){
$this->id = 'fast_delivery_shipping_method';
$this->method_title = __( 'Fast Delivery Shipping Method', 'woocommerce' );
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables
$this->enabled = $this->get_option( 'enabled' );
$this->title = $this->get_option( 'title' );
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable Fast Delivery Shipping', 'woocommerce' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Method Tittle', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => __( 'Fast Delivery Shipping', 'woocommerce' ),
)
);
}
public function is_available( $package ){
foreach ( $package['contents'] as $item_id => $values ) {
$_product = $values['data'];
$weight = $_product->get_weight();
if($weight > 10){
return false;
}
}
return true;
}
public function calculate_shipping($package){
//get the total weight and dimensions
$weight = 0;
$dimensions = 0;
foreach ( $package['contents'] as $item_id => $values ) {
$_product = $values['data'];
$weight = $weight + $_product->get_weight() * $values['quantity'];
$dimensions = $dimensions + (($_product->length * $values['quantity']) * $_product->width * $_product->height);
}
//calculate the cost according to the table
switch ($weight) {
case ($weight < 1):
switch ($dimensions) {
case ($dimensions <= 1000):
$cost = 3;
break;
case ($dimensions > 1000):
$cost = 4;
break;
}
break;
case ($weight >= 1 && $weight < 3 ):
switch ($dimensions) {
case ($dimensions <= 3000):
$cost = 10;
break;
}
break;
case ($weight >= 3 && $weight < 10):
switch ($dimensions) {
case ($dimensions <= 5000):
$cost = 25;
break;
case ($dimensions > 5000):
$cost = 50;
break;
}
break;
}
// send the final rate to the user.
$c= $this->add_rate( array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost
));
}
}