I am working on gravity forms add-on. I am saving all the values of gform fields in my database successfully after form submission using this hook gform_after_submission. Now I want to save the total pricing value but I don't get it I also see that the total pricing value coming from span.
So i search a lot but nothing found except some java script code:
<script type="text/javascript">
gform.addFilter( 'gform_product_total', function(total, formId) {
return total;
} );
</script>
But i don't get that how can i get this value in gform_after_submission hook
So please give me some suggestions
check bellow code . it's meet your requirement .
function saiful_gf_remove_money_symbol( $s ) {
return GFCommon::to_number( $s );
}
add_filter( 'saiful_gf_remove_money_symbol', 'saiful_gf_remove_money_symbol' );
add_filter( 'gform_product_info', 'add_fee', 10, 3 );
function add_fee( $product_info, $form, $lead ) {
$loop_price = 0;
if( isset( $product_info['products'] ) && count( $product_info['products'] ) > 0 ){
foreach ( $product_info['products'] as $data ){
if( isset( $data['options'] ) && count( $data['options'] ) > 0 ){
foreach ( $data['options'] as $key => $option ) {
$loop_price += floatval( $option['price'] );
}
}
// Save From Here total amount
$new_price = apply_filters( 'saiful_gf_remove_money_symbol',$data['price']) + $loop_price ;
}
}
return $product_info;
}
Related
Have been trying to solve this for a couple days and decided to just break down and ask for some insight. I'm basing what I have off of these two solutions:
Change items tax rate in WooCommerce checkout based on radio buttons
Add a dynamic fee based on a select field in WooCommerce Checkout
I'm trying to use a drop down/select to change the tax class on the checkout page of WooCommerce.
I've left a lot alone from the two above examples but am still not getting the results expected. I also need to store & place the delivery location in the admin area & emails but need to get this tax class change issue sorted first.
Below is what I have right now. It seems like it should be working but alas, no joy.
// Add a custom select fields for packing option fee
add_action( 'woocommerce_after_order_notes', 'checkout_shipping_form_packing_addition', 20 );
function checkout_shipping_form_packing_addition( ) {
$domain = 'woocommerce';
echo '<tr class="packing-select"><th>' . __('Pickup Location', $domain) . '</th><td>';
$chosen = WC()->session->get('chosen_packing');
// Add a custom checkbox field
woocommerce_form_field( 'chosen_packing', array(
'type' => 'select',
'class' => array( 'form-row-wide packing' ),
'options' => array(
'' => __("Please select a location...", $domain),
'BELGIUM - LOC' => sprintf( __("BELGIUM - LOC", $domain) ),
'BROOTEN - LOC' => sprintf( __("BROOTEN - LOC", $domain) ),
'OWATONNA - LOC' => sprintf( __("OWATONNA - LOC", $domain) ),
),
'required' => true,
), $chosen );
echo '</td></tr>';
}
// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_shipping_packing_script' );
function checkout_shipping_packing_script() {
// Only checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
WC()->session->__unset('chosen_packing');
?>
<script type="text/javascript">
jQuery( function($){
$('form.checkout').on('change', 'select#chosen_packing', function(){
var p = $(this).val();
console.log(p);
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'woo_get_ajax_data',
'packing': p,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log('response: '+result); // just for testing | TO BE REMOVED
},
error: function(error){
console.log(error); // just for testing | TO BE REMOVED
}
});
});
});
</script>
<?php
endif;
}
// Php Ajax (Receiving request and saving to WC session)
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
function woo_get_ajax_data() {
if ( isset($_POST['packing']) ){
$packing = sanitize_key( $_POST['packing'] );
WC()->session->set('chosen_packing', $packing );
echo json_encode( $packing );
}
die(); // Alway at the end (to avoid server error 500)
}
// Add a custom dynamic packaging fee
add_action( 'woocommerce_before_calculate_totals', 'change_tax_class_conditionally', 1000 );
function change_tax_class_conditionally( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$domain = "woocommerce";
$packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee
if ( $packing_fee === 'BELGIUM - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = '5 Percent';
}
if ( $packing_fee === 'BROOTEN - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = '0 Percent';
}
if ( $packing_fee === 'CHER-MAKE - LOC' ) {
//$label = __("Bag packing fee", $domain);
$tax_class = 'Reduced Rates';
}
// Loop through cart items
foreach( $cart->get_cart() as $cart_item ){
if( $choice === $field_value ) {
$cart_item['data']->set_tax_class($tax_class);
}
}
}
// Field validation, as this packing field is required
add_action('woocommerce_checkout_process', 'packing_field_checkout_process');
function packing_field_checkout_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['chosen_packing']) && empty($_POST['chosen_packing']) )
wc_add_notice( __( "Please choose a packing option...", "woocommerce" ), 'error' );
}
In my functions.php, I am trying to add a sold out message in the drop down menu for my product variants. So for example if I have shirt that has variants of small, medium and large and the large is out of stock, in the drop down menu the user should see the large option is disabled and contains a sold out message next to 'Large'. The other variants should remain active.
The issue I have with my code below is the following:
The code that is commented, this disables the correct product variant that is out of stock, but doesn't add the sold out message.
The active code does add the sold out message but it disables all product variants even though it's only one variant that is out of stock.
How can I fix the code to do what I need it to do?
/**
* Disable out of stock variations
* https://github.com/woocommerce/woocommerce/blob/826af31e1e3b6e8e5fc3c1004cc517c5c5ec25b1/includes/class-wc-product-variation.php
* #return Boolean
*/
// function wcbv_variation_is_active( $active, $variation ) {
// if( ! $variation->is_in_stock() ) {
// return false;
// }
// return $active;
// }
// add_filter( 'woocommerce_variation_is_active', 'wcbv_variation_is_active', 10, 2 );
add_action( 'woocommerce_variation_is_active', 'woocommerce_sold_out_dropdown' );
function woocommerce_sold_out_dropdown() {
?>
<script type="text/javascript">
jQuery( document ).bind( 'woocommerce_update_variation_values', function() {
jQuery( '.variations select option' ).each( function( index, el ) {
var sold_out = '<?php _e( 'sold out', 'woocommerce' ); ?>';
var re = new RegExp( ' - ' + sold_out + '$' );
el = jQuery( el );
if ( el.is( ':disabled' ) ) {
if ( ! el.html().match( re ) ) el.html( el.html() + ' - ' + sold_out );
} else {
if ( el.html().match( re ) ) el.html( el.html().replace( re,'' ) );
}
} );
} );
</script>
<?php
}
You can get what you need with this code (your code):
// disable options for unavailable variants
add_filter( 'woocommerce_variation_is_active', 'wcbv_variation_is_active', 10, 2 );
function wcbv_variation_is_active( $active, $variation ) {
if ( ! $variation->is_in_stock() ) {
return false;
}
return $active;
}
And now, to change the name of each individual option based on stock status you can use the woocommerce_variation_option_name hook like so:
add_filter( 'woocommerce_variation_option_name','add_stock_status_after_option_name', 10, 1 );
function add_stock_status_after_option_name( $option ) {
// only in frontend
if ( is_admin() ) {
return $option;
}
// get variable product object
global $product;
$variation_ids = $product->get_children();
foreach ( $variation_ids as $variation_id ) {
$variation = wc_get_product( $variation_id );
$variation_attributes = $variation->get_variation_attributes();
foreach ( $variation_attributes as $key => $value ) {
// slugify option name
$option_slug = sanitize_title( $option );
// check if the current option is equal to the variation slug
if ( $value == $option_slug ) {
// check if it is out of stock
if ( ! $variation->is_in_stock() ) {
return $option . ' (Out of stock)';
}
}
}
}
return $option;
}
The code has been tested and works correctly. It needs to be added to your theme's functions.php.
I'm using the code below to add three buttons to the WooCommerce checkout page so customers can leave a donation. It's working as it should be, but it would be great if I can highlight one of the buttons when a customer adds a donation to their cart and disable the other two.
Any thoughts on how I can get this to work?
add_action( 'woocommerce_review_order_before_submit', 'charity_checkout_add_on', 9999 );
function charity_checkout_add_on() {
$product_ids = array( 59355 );
$in_cart = false;
foreach( WC()->cart->get_cart() as $cart_item ) {
$product_in_cart = $cart_item['variation_id'];
if ( in_array( $product_in_cart, $product_ids ) ) {
$in_cart = true;
break;
}
}
if ( ! $in_cart ) {
echo '<div id="charity-donation">';
echo '<h6>Heading text</h6>';
echo '<p>Explanation</p>';
echo '<a class="charity-button" href="?add-to-cart=59356">€0,50</a><a class="charity-button" href="?add-to-cart=59357">€1,00</a><a class="charity-button last" href="?add-to-cart=59358">€2,50</a>';
echo '</div>';
}
}
Instead of hard-coding the HTML for the buttons you can loop over the $product_ids array to fetch and build up the HTML dynamically. This will work for both simple and variable products. You should always escape these values where possible: see https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/
You could then simply add a css class to the button if the product is in the cart by comparing its ID against any of the IDs in the cart.
Issues with add to cart in URL
If you don't redirect to the cart page after the product has been added, when the checkout refreshes the ?add-to-cart=ID query parameter will remain in the URL. This means that if you refresh the checkout page, the product will be added again. To solve this, either tick "Redirect to the basket page after successful addition" in Woocommerce Settings > Products > General or change the add-t-cart url to something like yourdomain.com/cart/?add-to-cart=ID
Try:
add_action( 'woocommerce_review_order_before_submit', 'charity_checkout_add_on', 20 );
function charity_checkout_add_on() {
$product_ids = array( 59356, 59357, 59358 );
$products_in_cart = array();
$button_data = array();
// Gather product cart items in array
foreach( WC()->cart->get_cart() as $cart_item ) {
$cart_product = $cart_item['data'];
$products_in_cart[] = $cart_product->get_id();
}
// Dynamically generate buttons
$button_html = '';
$last_button = end( $product_ids );
foreach( $product_ids as $product_id ) {
if( $product = wc_get_product( $product_id ) ) {
$in_cart = ( in_array( $product->get_id(), $products_in_cart ) ) ? true : false;
$button_classes = 'charity-button';
if( $in_cart ) {
$button_classes.= ' disabled';
}
if( $product_id === $last_button ) {
$button_classes.= ' last';
}
$button_html .= sprintf(
'<a class="%s"%s>%s</a>',
esc_attr( $button_classes ),
( $in_cart ) ? '' : esc_url( 'href="?add-to-cart=' . $product->get_id() . '"' ),
esc_html( get_woocommerce_currency_symbol() . $product->get_price() )
);
};
}
?>
<h4>Make a Donation?</h4>
<div id="charity-donation">
<h6>Heading text</h6>
<p>Explanation</p>
<?php echo $button_html; ?>
</div>
<?php
}
Your css class then could be something like:
.charity-button.disabled {
cursor: not-allowed;
opacity: 0.5;
}
So i first created 2 fields, the custom field to display the calculated price and a hidden field that has the percentage value
/*Custom price field - to create custom field for simple product*/
add_action( 'woocommerce_product_options_pricing', 'wc_cost_product_field' );
function wc_cost_product_field() {
woocommerce_wp_text_input(
array(
'id' => 'cost_price',
'name' =>'cost_price',
'class' => 'wc_input_price short',
'desc_tip' => 'true',
'description' => __( 'Your Profit price is calculated as ((Vendor price x 15%) + 500 + vendor price )', 'woocommerce' ),
'label' => __( 'Total Price with Profit', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')'
)
);
woocommerce_wp_hidden_input(
array(
'id' => '_hidden_field[' . $post->ID . ']',
'name' => 'per',
'value' => 0.15
)
);
}
So i saved the custom field to always display
/*Custom price field - to save custom field for simple product*/
add_action( 'save_post', 'wc_cost_save_product' );
function wc_cost_save_product( $product_id ) {
// stop the quick edit interferring as this will stop it saving properly, when a user uses quick edit feature
if (wp_verify_nonce($_POST['_inline_edit'], 'inlineeditnonce'))
return;
// If this is a auto save do nothing, we only save when update button is clicked
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( isset( $_POST['cost_price'] ) ) {
if ( is_numeric( $_POST['cost_price'] ) )
update_post_meta( $product_id, 'cost_price', $_POST['cost_price'] );
} else delete_post_meta( $product_id, 'cost_price' );
$hidden = $_POST['_hidden_field'][ $post_id ];
if( ! empty( $hidden ) ) {
update_post_meta( $post_id, '_hidden_field', esc_attr( $hidden ) );
}
}
?>
Then i added the script that will call and trigger the value then render it to the custom field
<script>
const calculateprofit_price = (profitPrice, percent) => {
profitPrice = parseFloat(profitPrice);
percent = parseFloat(pecent);
return ((profitPrice * percent) + 500 + profitPrice).toFixed(2); // profit price
}
const $price = $('input[name="_regular_price"]'),
$per = $('input[name="per"]'),
$profit_price = $('input[name="cost_price"]');
$price.add( $per ).on('input', () => { // price and percent inputs events
let profit_price = $price.val(); // Default to profit price
if ( $per.val().length ) { // if value is entered- calculate profit_price
profit_price = calculateprofit_price($price.val(), $per.val());
}
$profit_price.val( profit_price );
});
$price.trigger('input');
</script>
I have checked online to see available codes to help but to no avail, pls help.
This is an image of what I'm trying to achieve
displaying calculated regular price in custom field
I'm currently in a problem where I have to add option in Cart with checkbox (for each item in Cart) which will change item's price with one from custom attribute.
This is an illustration of it (I have already created custom field, just need price updating function when button "Update cart" is clicked)
Code for displaying checkbox for each item (/woocommerce/templates/cart/cart.php):
<td class="product-url">
<?php
$html = sprintf( '<div class="lorem"><input type="checkbox" name="cart[%s][lorem]" value="%s" size="4" class="input-text url text" /> Lorem price</div>', $cart_item_key, esc_attr( $values['url'] ) );
echo $html;
?>
</td>
Here I'm assuming that lorem price is stored in custom meta field associated with meta_key your_custom_meta_field
Use following code in your theme's function.php file
add_action( 'woocommerce_before_calculate_totals', 'my_custom_calculate_totals' );
function my_custom_calculate_totals( $cart ) {
if ( ! empty( $cart->cart_contents ) ) {
$lorem_price = array();
if ( ! empty( $_REQUEST['cart'] ) ) { // check if any of the checkboxes is checked
WC()->session->set( 'my_lorem_price', $_REQUEST['cart'] ); // set all checkboxes information in session
$lorem_price = $_REQUEST['cart'];
}
if ( empty( $lorem_price ) ) {
$lorem_price = WC()->session->get( 'my_lorem_price' ); // fetch all checkboxes information from session
}
if ( empty( $lorem_price ) ) {
return; // don't do anything if any of the checkboxes is not checked
}
foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
if ( isset( $lorem_price[ $cart_item_key ]['lorem'] ) ) {
// Use following line if lorem price is set at variation level
$id = ( ! empty( $cart_item['variation_id'] ) && $cart_item['variation_id'] > 0 ) ? $cart_item['variation_id'] : $cart_item['product_id'];
// Use following line if lorem price is set at product level
// $id = $cart_item['product_id'];
$new_price = get_post_meta( $id, 'your_custom_meta_field', true ); // fetch price from custom field
$cart_item['data']->price = $new_price;
}
}
}
}