I'm trying to change the currency depending on the customer's billing country. Is it possible to do that maybe with an override of the "tax calculation" function as it is updated when the customer change the country ?
At the moment, I have this function (function.php) :
add_filter('wcml_client_currency','change_currency');
function change_currency($client_currency){
global $woocommerce;
$country = $woocommerce->customer->get_country();
if($country == 'CH') {
$client_currency = 'CHF'; //currency code
} else {
$client_currency = 'EUR'; //currency code
}
return $client_currency;
}
Thanks for your help.
You can use this following code:
add_filter('woocommerce_get_price', 'return_custom_price', $product, 2);
function return_custom_price($price, $product) {
global $post, $woocommerce;
$tot_qty = $woocommerce->cart->cart_contents_count;
// Array containing country codes
$county = array('NZ', 'AU', 'GB', 'IE');
// Amount to increase by
//$amount = 10;
change_existing_currency_symbol('NZD$', 'NZD');
if($woocommerce->customer->get_shipping_country() == 'NZ'){
$amount = 0.00;
$amount = 26.19;
}
else if($woocommerce->customer->get_shipping_country() == 'GB'){
$amount = 0.00;
$amount = 19.04;
}
else if($woocommerce->customer->get_shipping_country() == 'IE'){
$amount = 0.00;
$amount = 19.04;
}
else {
$amount = 0.00;
$amount = 28.19;
}
//echo $amount;
// If the custromers shipping country is in the array
if ( in_array( $woocommerce->customer->get_shipping_country(), $county ) ){
// Return the price plus the $amount
return $new_price = $amount;
die();
} else {
// Otherwise just return the normal price
return $price;
die();
}
}
add_filter('woocommerce_currency_symbol', 'change_existing_currency_symbol', 10, 2);
function change_existing_currency_symbol( $currency_symbol, $currency ) {
global $post, $woocommerce;
$my_country = $woocommerce->customer->get_shipping_country();
switch( $my_country ) {
case 'GB': $currency_symbol = '£';
break;
case 'NZ': $currency_symbol = '$';
break;
case 'IE': $currency_symbol = '€';
break;
default:
$currency_symbol = '$';
}
return $currency_symbol;
}
Related
I am running into issues with the Woocommerce cart total only displaying the price of the last item added to the cart. Individual items prices are not adding up to the total price correctly, it only show the price of the last item.
Here is the code I'm using for overriding the price of the products added to the cart:
function action_woocommerce_before_cart_table() {
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach ($items as $item => $values) {
$price = 0;
if (array_key_exists('addons', $values) && count($values['addons']) > 0) {
foreach ($values['addons'] as $value) {
$price = $price + $value['price'];
}
} else {
$regular_price = get_post_meta($values['product_id'], '_regular_price', true);
$sale_price = get_post_meta($values['product_id'], '_sale_price', true);
$price = $regular_price;
}
$values['data']->set_price($price);
}
}
add_action('woocommerce_before_cart_table', 'action_woocommerce_before_cart_table', 10, 0);
function action_woocommerce_checkout_before_order_review() {
foreach (WC()->cart->get_cart() as $item => $values) {
$price = 0;
$quantity = $values['quantity'];
if (array_key_exists('addons', $values) && count($values['addons']) > 0) {
foreach ($values['addons'] as $value) {
$price = $price + $value['price'];
}
} else {
$regular_price = get_post_meta($values['product_id'], '_regular_price', true);
$sale_price = get_post_meta($values['product_id'], '_sale_price', true);
$price = $regular_price;
}
// $final_price = $quantity * $price;
$values['data']->set_price($price);
}
}
add_action('woocommerce_review_order_before_cart_contents', 'action_woocommerce_checkout_before_order_review', 10, 0);
function woocommerce_calculate_totals($cart) {
$cart_sub_total = 0;
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach ($items as $item => $values) {
$price = 0;
$quantity = $values['quantity'];
if (array_key_exists('addons', $values) && count($values['addons']) > 1) {
foreach ($values['addons'] as $value) {
$price = $price + $value['price'];
}
} else {
$regular_price = get_post_meta($values['product_id'], '_regular_price', true);
$sale_price = get_post_meta($values['product_id'], '_sale_price', true);
$price = $regular_price;
}
$final_price = $quantity * $price;
$cart_sub_total = $final_price;
$values['data']->set_price($cart_sub_total);
}
WC()->cart->subtotal = $cart_sub_total;
$cart->sub_total = $cart_sub_total;
$coupons = WC()->cart->get_coupons();
$cupon_price = 0;
if (!empty($coupons)) {
foreach ($coupons as $code => $coupon) {
$cupon_price = $cupon_price + $coupon->get_amount();
}
}
$new_price = $cart_sub_total - $cupon_price;
WC()->cart->total = $new_price;
$cart->total = $new_price;
}
add_action('woocommerce_before_cart_totals', 'woocommerce_calculate_totals', 30);
add_action('woocommerce_after_calculate_totals', 'woocommerce_calculate_totals', 30);
Appreciate any help.
You're not accumulating the subtotal in your woocommerce_calculate_totals function. You're writing $cart_sub_total = $final_price; every time so you'll only have the price of the last item at the end. Instead it should be $cart_sub_total = $cart_sub_total + $final_price;.
I have an app where the user is able to choose themes and plugins but they are also able to choose none of the two. So to check all the possible options I need a 4 clause if-statement to check every situation. In the meantime, this if-statement grew exponentially and now it's very large. I used Repository for some bits to refactor the if-statement a bit but its still way too large and uclear. This is the if-statement
public function store(Request $request)
{
$selectedPlugin = null;
$selectedPlugins = array();
$price = null;
foreach($request->input('plugin') as $key => $value) {
if ($value === 'selected') {
$selectedPlugin = $key;
$plugin = Product::find($selectedPlugin);
if($plugin == null)
{
continue;
} elseif ($plugin != null) {
$price += $plugin->price;
echo "ID: " . $plugin->id . "<br>";
$selectedPlugins[$plugin->id] = $plugin->toArray();
$request->session()->put('chosen_plugins.' . 'PluginID' . $plugin->id, $plugin->toArray());
$request->session()->put('chosen_plugins.' . 'PluginID' . $plugin->id .'.composer_package', $plugin->productable->composer_package);
}
}
}
if(session()->exists('chosen_plugins') == true) {
$products = Session::get('chosen_plugins');
if(session()->exists('chosen_theme') == true)
{
$products['theme'] = Session::get('chosen_theme');
$themePrice = Session::get('chosen_theme')['price'];
$subtotal = $price + $themePrice;
$vat = 21/100 * $subtotal;
$priceSum = $subtotal + $vat;
} elseif (session()->exists('chosen_theme') == false) {
$subtotal = $price;
$vat = 21/100 * $subtotal;
$priceSum = $subtotal + $vat;
}
$data = [$subtotal, $vat, $priceSum];
$order = $this->_orderRepository->createOrderIfSessionExist($data, $products);
return redirect()->to('/ordersummary/'. $order->id);
} elseif (session()->exists('chosen_plugins') == false ) {
if(session()->exists('chosen_theme') == true)
{
$theme = Session::get('chosen_theme');
$subtotal = $theme['price'];
$vat = 21/100 * $subtotal;
$priceSum = $subtotal + $vat;
} elseif (session()->exists('chosen_theme') == false) {
$subtotal = 35;
$vat = 21/100 * $subtotal;
$priceSum = $subtotal + $vat;
}
$data = [$subtotal, $vat, $priceSum];
$order = $this->_orderRepository->createOrderIfSessionDoesntExist($data);
if (session()->exists('chosen_theme') == true) {
$orderItems = new Orderitems;
$orderItems->order_id = $order->id;
$orderItems->product_id = $theme['id'];
$orderItems->price = $theme['price'];
$orderItems->save();
return redirect()->to('/ordersummary/'. $order->id);
} elseif (session()->exists('chosen_theme') == false) {
return redirect()->to('/ordersummary/'. $order->id);
}
}
}
I need some help to refactor this if-statement. Thanks in advance!
This is the code I have in one of my php plugin file.
add_filter('woocommerce_cart_totals_order_total_html','test_func');
function test_func() {
global $woocommerce, $totalship;
$cart_subtotal = (float)$woocommerce->cart->subtotal;
if( $cart_subtotal < 1000 ) {
$cart_subtotal01 = $woocommerce->cart->get_cart_subtotal();
$cart_subtotal11 = explode('</span>', $cart_subtotal01);
$text_tax ='';
if($cart_subtotal11[1]) {
$text_tax = $cart_subtotal11[1];
}
$allcarttotal = $cart_subtotal+$totalship;
$value = '<strong><span class="amount">Rs. ' . $allcarttotal . '</span>'.$text_tax.'</strong>';
$citrus_total_val = $value;
return $citrus_total_val;
//return $value;
}
else {
$docart_total = $cart_subtotal - $totalship;
$citrus_total_val = $docart_total;
return $citrus_total_val;
//return $docart_total;
}
}
global $citrus_total_val;
I am trying to pass the value of $citrus_total_val to another plugin for payment gateway.
This is the code:
global $citrus_total_val;
//Setup URL and signatue etc.
$currencycode = get_woocommerce_currency();
$merchantTxnId = $order_id;
$orderAmount = $citrus_total_val;
But the value is not passed here. What am I doing wrong?
Try this:
$citrus_total_val = '';
add_filter('woocommerce_cart_totals_order_total_html','test_func');
function test_func() {
global $woocommerce, $totalship;
global $citrus_total_val;
$cart_subtotal = (float)$woocommerce->cart->subtotal;
if( $cart_subtotal < 1000 ) {
$cart_subtotal01 = $woocommerce->cart->get_cart_subtotal();
$cart_subtotal11 = explode('</span>', $cart_subtotal01);
$text_tax ='';
if($cart_subtotal11[1]) {
$text_tax = $cart_subtotal11[1];
}
$allcarttotal = $cart_subtotal+$totalship;
$value = '<strong><span class="amount">Rs. ' . $allcarttotal . '</span>'.$text_tax.'</strong>';
$citrus_total_val = $value;
return $citrus_total_val;
//return $value;
}
else {
$docart_total = $cart_subtotal - $totalship;
$citrus_total_val = $docart_total;
return $citrus_total_val;
//return $docart_total;
}
}
try putting it in the function, like you did with global $woocommerce, $totalship;
add_filter('woocommerce_cart_totals_order_total_html','test_func');
function test_func() {
global $woocommerce, $totalship;
global $citrus_total_val;
$cart_subtotal = (float)$woocommerce->cart->subtotal;
if( $cart_subtotal < 1000 ) {
$cart_subtotal01 = $woocommerce->cart->get_cart_subtotal();
$cart_subtotal11 = explode('</span>', $cart_subtotal01);
$text_tax ='';
if($cart_subtotal11[1]) {
$text_tax = $cart_subtotal11[1];
}
$allcarttotal = $cart_subtotal+$totalship;
$value = '<strong><span class="amount">Rs. ' . $allcarttotal . '</span>'.$text_tax.'</strong>';
$citrus_total_val = $value;
return $citrus_total_val;
//return $value;
}
else {
$docart_total = $cart_subtotal - $totalship;
$citrus_total_val = $docart_total;
return $citrus_total_val;
//return $docart_total;
}
}
At the moment, I have a shopping cart that will add an item to the cart session. If another of the same item is added to the cart, it displays duplicate items, each with a quantity of 1.
What do I need to add/change for the code to update the quantity of an existing item? Instead of adding a duplicate item.
add_to_cart.php
session_start();
include 'cart.php';
$item_id = $_POST['item_id'];
$qty = $_POST['qty'];
$counter = $_SESSION['counter'];
$cart = new Cart();
if ($counter>0)
{
$cart = unserialize($_SESSION['cart']);
}
else
{
$_SESSION['counter'] = 0;
$_SESSION['cart'] = "";
}
if (($item_id == "")or ($qty < 1))
{
header("Location: products.php");
}
else
{
require_once('conn_db.php');
$query = "SELECT item_name, price FROM products WHERE (item_id=$item_id)";
$result = mysql_query($query) or die("Database Error");
if(mysql_num_rows($result) == 1)
{
$price = mysql_result($result, 0,"price");
$item_name = mysql_result($result, 0, "item_name");
$new_item = new Item($item_id, $item_name, $qty, $price);
$cart->add_item($new_item);
$_SESSION['counter'] = $counter+1;
$_SESSION['cart'] = serialize($cart);
header("Location: products.php");
mysql_close();
}
else
{
header("Location: products.php");
}
}
cart.php
class Item {
var $item_id;
var $item_name;
var $qty;
var $price;
var $deleted = false;
function get_item_cost() {
return $this->qty * $this->price;
}
function delete_item() {
$this->deleted = true;
}
function Item($item_id, $item_name, $qty, $price) {
$this->item_id = $item_id;
$this->item_name = $item_name;
$this->qty = $qty;
$this->price = $price;
}
function get_item_id() {
return $this->item_id;
}
function get_item_name() {
return $this->item_name;
}
function get_qty() {
return $this->qty;
}
function get_price() {
return $this->price;
}
}
class Cart {
var $items;
var $depth;
function Cart() {
$this->items = array();
$this->depth = 0;
}
function add_item($item) {
$this->items[$this->depth] = $item;
$this->depth++;
}
function delete_item($item_no) {
$this->items[$item_no]->delete_item();
}
function get_depth() {
return $this->depth;
}
function get_item($item_no) {
return $this->items[$item_no];
}
}
Fairly quick example, should put in you in the right direction. You'll need to chance your add_item() to check to see if the cart already contains the item
function add_item($item) {
$item_already_exists = false;
foreach ($this->items as $depth_id => $item_in_cart) { // loop through the current contents of the cart
if ($item_in_cart->get_item_id() == $item->get_item_id()) { // if the item already exists in the cart
$item_already_exists = true;
$item_exists_at = $depth_id;
break;
}
}
if ($item_already_exists == true) { //update the existing item
$this->items[$item_exists_at]->update_qty($item->get_qty());
} else { // add the new item
$this->items[$this->depth] = $item;
$this->depth++;
}
}
Then you'll need to create an update_quantity() in your Item class
function update_qty($qty) {
$this->qty += $qty;
}
Before adding the item check if it already exists in the shopping cart. If False, add it. If True, just change the quantity! :)
I guys i try to make something link this with an override on a prestashop function ConvertPrice (in Tools class) :
<span>750</span>,00€
With this code in my override :
/**
* Return price converted
*
* #param float $price Product price
* #param object $currency Current currency object
* #param boolean $to_currency convert to currency or from currency to default currency
*/
public static function convertPrice($price, $currency = NULL, $to_currency = true)
{
if ($currency === NULL)
$currency = Currency::getCurrent();
elseif (is_numeric($currency))
$currency = Currency::getCurrencyInstance($currency);
$c_id = (is_array($currency) ? $currency['id_currency'] : $currency->id);
$c_rate = (is_array($currency) ? $currency['conversion_rate'] : $currency->conversion_rate);
if ($c_id != (int)(Configuration::get('PS_CURRENCY_DEFAULT')))
{
if ($to_currency)
$price *= $c_rate;
else
$price /= $c_rate;
}
$price = explode(".", strval($price));
$temp = '<span>'.$price[0]."</span>";
$price[0] = $temp;
return implode(".", $price);
}
I founded a solution by myself, i didn't edit the right function so there is the correct way :
public static function displayPrice($price, $currency = NULL, $no_utf8 = false){
if ($currency === NULL)
$currency = Currency::getCurrent();
if (is_int($currency))
$currency = Currency::getCurrencyInstance((int)($currency));
$c_char = (is_array($currency) ? $currency['sign'] : $currency->sign);
$c_format = (is_array($currency) ? $currency['format'] : $currency->format);
$c_decimals = (is_array($currency) ? (int)($currency['decimals']) : (int)($currency->decimals)) * _PS_PRICE_DISPLAY_PRECISION_;
$c_blank = (is_array($currency) ? $currency['blank'] : $currency->blank);
$blank = ($c_blank ? ' ' : '');
$ret = 0;
if (($isNegative = ($price < 0)))
$price *= -1;
$price = self::ps_round($price, $c_decimals);
switch ($c_format){
/* X 0,000.00 */
case 1:
$ret = $c_char.$blank.number_format($price, $c_decimals, '.', ',');
break;
/* 0000,00 X*/
case 2:
$ret = number_format($price, $c_decimals, ',', '').$blank.$c_char;
$price = explode(",", strval($ret));
$price[0] = '<span>'.$price[0]."</span>";
$ret = implode(",", $price);
break;
/* X 0.000,00 */
case 3:
$ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.');
break;
/* 0,000.00 X */
case 4:
$ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char;
break;
}
if ($isNegative)
$ret = '-'.$ret;
if ($no_utf8)
return str_replace('€', chr(128), $ret);
return $ret;
}
In override/classes/Tools.php