How to calculate Custom order total in WooCommerce edit order? - wordpress

Currently, I'm working on a WooCommerce (5.2.2) project. My client wants to create a custom input field for Advance payment in the Backend (not for customers) so that when my client received an advance payment from the customer (delivery purpose) they can add manually and order total auto adjust from the backend. So I've wright a code and create a custom field in the post meta table and use that meta table value to calculate the total order, it works but I have to refresh twice to get Order's total new value. here is my code and tell me how to fix it -
add_action( 'manage_shop_order_posts_custom_column' , array(&$this,'add_custom_column_content'), 11, 2 );
add_action( 'woocommerce_admin_order_totals_after_discount', array(&$this, 'vp_add_sub_total'), 10, 1);
add_action( 'woocommerce_process_shop_order_meta', array(&$this, 'save_order_custom_field_meta_data'), 12, 2 );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('_advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advancePayment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
//Display Advance Payment and calculate
function vp_add_sub_total( $the_order ) {
global $post, $the_order;
if ( empty( $the_order ) || $the_order->get_id() !== $post->ID ) {
$the_order = wc_get_order( $post->ID );
}
?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
</tr>
<?php
$getTotal = $the_order->get_total();
$updateTotal = $getTotal - get_post_meta($post->ID, "_advance_payment", true);
$the_order->set_total($updateTotal);
$the_order->save();
}
Note : I create a small plugin for this advance payment.
Video link for reference : https://www.awesomescreenshot.com/video/3589010?key=b26b5951753bfdc8a969b53f526a36d1

You need to calculate Advance Payment before display. you can use woocommerce_admin_order_item_headers action hook.
add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('_advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advancePayment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advancePayment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, '_advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
function calculate_advance_payment( $the_order ) {
$getTotal = $the_order->get_total();
$updateTotal = $getTotal - get_post_meta($the_order->get_id(), "_advance_payment", true);
$the_order->set_total($updateTotal);
$the_order->save();
}
function vp_add_sub_total( $the_order ) {
global $post, $the_order; ?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "_advance_payment", true));?></td>
</tr><?php
}

I was looking for this solution. Unfortunately the solution posted above gave this error "Unsupported operand types: string - string". I used var_dump($getTotal); var_dump( $advanced_payment); to analyze the data. Since it's adding+ 2 numbers that are in a string add (int) or (float) before variable $variable. float is used when numbers contain a decimal. Use (int) for integers that are whole numbers. Example: (int)$variable , (float)$variable. Here's an article which helped me. Here's the modified solution which gave no errors and updated the order total.
add_action( 'woocommerce_admin_order_item_headers', 'calculate_advance_payment', 10, 1);
add_action( 'woocommerce_admin_order_totals_after_discount', 'vp_add_sub_total', 10, 1);
add_action( 'woocommerce_process_shop_order_meta', 'save_order_custom_field_meta_data', 12, 2 );
add_action( 'woocommerce_admin_order_data_after_order_details', 'editable_order_custom_field' );
// Output a custom editable field in backend edit order pages under general section
function editable_order_custom_field( $order ){
// Get "Delivery Type" from meta data (not item meta data)
$updated_advance_payment = $order->get_meta('advance_payment');
// Replace "Delivery Type" value by the meta data if it exist
$advanced_payment = $updated_advance_payment ? $updated_advance_payment : ( isset($item_value) ? $item_value : '');
// Display the custom editable field
woocommerce_wp_text_input(
array(
'id' => 'advance_payment',
'label' => __("Advance Payment:", "woocommerce"),
'value' => $advanced_payment,
'wrapper_class' => 'form-field-wide',
)
);
}
// Save the custom editable field value as order meta data and update order item meta data
function save_order_custom_field_meta_data( $post_id, $post ){
//global $order;
if( isset( $_POST[ 'advance_payment' ] )){
update_post_meta( $post_id, 'advance_payment', sanitize_text_field( $_POST[ 'advance_payment' ] ) );
// Update the existing item meta data
if( isset( $_POST[ 'item_id_ref' ] ) ){
wc_update_order_item_meta( $_POST[ 'item_id_ref' ], 'Advance Payment', $_POST[ 'advance_payment' ] );
}
}
}
function calculate_advance_payment( $order ) {
$order_id = $order->get_id();
$getTotal = $order->get_total();
$advanced_payment = get_post_meta($order_id, 'advance_payment', true);
$order_total = (float)$getTotal - (float)$advanced_payment;
$order->set_total( $order_total );
$order->save();
}
function vp_add_sub_total( $order ) {
global $post, $order;
?>
<tr>
<td class="label">Advance Payment:</td>
<td width="1%"></td>
<td class="total"><?php echo wc_price(get_post_meta($post->ID, "advance_payment", true));?></td>
</tr><?php
}

Related

Verifying Userprofile "Uniqueness" of Meta Value at the time of creation for wordpress user custom field meta-key "association_id"

I have a custom user profile field "association_id". I can see the field the underlying wordpess db table (usermeta) with the 'meta_key' as "association_id" and the 'meta_value' whatever that I maintain for each user.
add_action( 'show_user_profile', 'rudr_profile_fields' );
add_action( 'edit_user_profile', 'rudr_profile_fields' );
function rudr_profile_fields( $user )
{
// let's get custom field values
$association_id = get_user_meta( $user->ID, 'association_id', true );
?>
<h3>Association Information</h3>
<table class="form-table">
<tr>
<th><label for="association_id">Association_ID</label></th>
<td>
<input type="text" name="association_id" id="association_id" value="<?php echo esc_attr( $association_id ) ?>" class="regular-text" />
<span class="description"><?php _e("Please enter your Association ID (For eg. if RCIC, your license number)."); ?></span>
</td>
</tr>
</table>
<?php
}
//avoid self to edit //
//add_action( 'personal_options_update', 'rudr_save_profile_fields' ); //
add_action( 'edit_user_profile_update', 'rudr_save_profile_fields' );
function rudr_save_profile_fields( $user_id ) {
if( ! isset( $_POST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_POST[ '_wpnonce' ], 'update-user_' . $user_id ) ) {
return;
}
if( ! current_user_can( 'edit_user', $user_id ) ) {
return;
}
/* HOLDING SPACE FOR ENHANCED SNIPPED */
//include in the list view of users
add_filter( 'manage_users_columns', 'column_register_association_id' );
add_filter( 'manage_users_custom_column', 'column_display_association_id', 10, 3 );
function column_register_association_id( $columns )
{
$columns['association_id'] = 'association_id';
return $columns;
}
function column_display_association_id( $value, $column_name, $user_id )
{
$user_info = get_user_meta( $user_id, 'association_id', true );
if($column_name == 'association_id') return $user_info;
return $value;
}
//Sort association_id column
function association_id_register_sortable( $columns ) {
$columns['association_id'] = 'association_id';
return $columns;
}
add_filter( 'manage_users_sortable_columns', 'association_id_register_sortable' );
function association_id_orderby( $vars ) {
if ( isset( $vars['orderby'] ) && 'association_id' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'association_id',
'orderby' => 'meta_value'
) );
}
return $vars;
}
add_filter( 'request', 'association_id_orderby' );
The preceding works fine and creates a meta key for storing meta value in the metadata wp table.
I want this custom user profile field value that I enter in the user admin page to be unique, verifying with the underlying wordpress database table. So I enhanced the code at the time of creation with the additional lines below. I tried these two snippets in the wordpress child theme, but it throws a critical error. I am on PHP version 8.
I tried two options below at the placeholder location in the above code, replacing the line below.
/* HOLDING SPACE FOR ENHANCED SNIPPED */
Option 1 that I tried.
$checkMeta=$wpdb->get_results("SELECT user_id FROM $wpdb->usermeta WHERE meta_key='association_id' AND meta_value=".$association_id,ARRAY_A);
if (empty($checkMeta)) {
update_user_meta( $user_id, 'association_id', sanitize_text_field( $_POST[ 'association_id' ] ) );
}
Option 2 that I tried.
$mysqli = new mysqli(SERVER, DBUSER, DBPASS, DATABASE); $result = $mysqli->query("SELECT user_id FROM usermeta WHERE meta_key='association_id' && meta_value=$association_id "); if($result->num_rows == 0) { // row not found, do stuff update_user_meta( $user_id, 'association_id', sanitize_text_field( $_POST[ 'association_id' ] ) ); } else { // row found, do stuff echo ' This ID is already used.'; } $mysqli->close();
Both failed to activate when I tried to create or change the 'association_field' value, throwing critical errors and aborting.

WooCommerce custom order itemmeta display my account view order page

I created a custom field for the ecommerce admin order item meta. Everything is fine.
I would like to display the Custom Fields MetaValue on My Account's Order Details page. But nothing is being displayed. Based on Save Order item custom field in Woocommerce Admin order pages answer code, this is my attempt
function add_order_item_custom_field( $item_id, $item ) {
woocommerce_wp_text_input( array(
'id' => 'v_number'.$item_id,
'label' => __( 'V Number : ', 'ctxt' ),
'description' => __( 'Enter the title of your custom text field.', 'ctxt' ),
'desc_tip' => true,
'class' => 'v_number_class',
'value' => wc_get_order_item_meta( $item_id, '_v_number' ),
) );
}
add_action( 'woocommerce_before_order_itemmeta', 'add_order_item_custom_field', 10, 2 );
// Save the custom field value
function save_order_item_custom_field_value( $post_id, $post ){
$order = wc_get_order( $post_id );
foreach ( $order->get_items() as $item_id => $item ) {
if( isset( $_POST['v_number'.$item_id] ) ) {
$item->update_meta_data( '_v_number', sanitize_text_field( $_POST['v_number'.$item_id] ) );
$item->save();
}
}
$order->save();
}
add_action('save_post', 'save_order_item_custom_field_value' );
// Display meta my account view order page
printf (
'<p><a>V Number : <strong>' . $order->get_meta('_v_number') . '</strong></a></p>'
);
it should print your custom order meta value.
add_action( 'woocommerce_view_order', 'print_custom_order_meta' );
function print_custom_order_meta( $order_id ){
$order = wc_get_order($order_id);
foreach( $order->get_items() as $item ) {
echo 'V Number for '. $item->get_name() .' - ' . $item->get_meta( '_v_number', true ) . '<br>';
}
}
edit
for need to show metavalue after each product item you need to hook with a different action like this.
add_action('woocommerce_order_item_meta_end', 'show_order_meta', 11, 3);
function show_order_meta( $item_id, $item, $order ) {
echo '<br>V Number for '. $item->get_name() .' - ' . $item->get_meta( '_v_number', true ) . '<br>';
}

Add custom select field with validation to WooCommerce checkout page if certain products are in cart

I wish to add a custom select field with validation to the WooCommerce checkout page if certain products are in cart.
With my current code I retrieve the value of my custom WooCommerce form field. However, it display "array" at the order page.
I have an select field which have an option of 1 and 0. Upon selection of the select field, i want it to display either 1 or 0 at the order page but im unable to do so.
Please guide me on what should i do with my current codes:
//AMBASSADOR CUSTOM CHECKOUT FIELDS, CONTENT add marketplace for sameday TEST
add_action( 'woocommerce_after_checkout_billing_form', 'aym_custom_checkout_field' );
function aym_custom_checkout_field( $checkout ) {
//Check if Product in Cart
$prod_in_cart_17563 = aym_is_conditional_product_in_cart_17563( 212 );
if ( $prod_in_cart_17563 === true ) {
$domain = 'wocommerce';
$default = 'Y';
woocommerce_form_field( '_my_field_name', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'label' => __( 'Market Place - Please Select Y to complete this order' ),
'required' => true,
'options' => array(
'Y' => __('1'),
'N' => __('0')
),'default' => $default),
$checkout->get_value( '_my_field_name' ) );
}
}
//AMBSSADOR BUNDLE add marketplace for same day pa rt 2
function aym_is_conditional_product_in_cart_17563( $product_id ) {
//Check to see if user has product in cart
global $woocommerce;
//flag no product in cart
$prod_in_cart_17563 = false;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id === $product_id ) {
//product is in cart!
$prod_in_cart_17563 = true;
}
}
return $prod_in_cart_17563;
}
//process orders in order page
// Custom checkout fields validation
add_action( 'woocommerce_checkout_process', 'custom_checkout_field_process' );
function custom_checkout_field_process() {
if ( isset($_POST['_my_field_name']) && empty($_POST['_my_field_name']) )
wc_add_notice( __( 'Please fill in "My 1st new field".' ), 'error' );
}
// Save custom checkout fields the data to the order
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_meta', 10, 2 );
function custom_checkout_field_update_meta( $order, $data ){
if( isset($_POST['_my_field_name']) && ! empty($_POST['_my_field_name']) )
$order->update_meta_data( '_my_field_name', sanitize_text_field( $_POST['_my_field_name'] ) );
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['_my_field_name']) update_post_meta( $order_id, 'My Field', esc_attr($_POST['_my_field_name']));
}
// View fields in Edit Order Page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_fields_value_admin_order', 10, 1 );
function display_custom_fields_value_admin_order( $order ){
// Display the delivery option
if( $delivery_option = $order->get_meta('_my_field_name') )
echo '<p><strong>'.__('Delivery type').':</strong> ' . $delivery_option . '</p>';
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ) {
if( $selectoption = $order->get_meta('_my_field_name') ) {
//$value = wc_get_hearaboutus_options()[$selectoptions];
$meta= get_post_meta( $post->ID, $selectoption, true );
$myvalues = unserialize( $meta );
echo '<p><strong>'.__('Market_Place').':</strong> ' . $myvalues . '</p>';
}
}
I have partly rewritten / modified your code with some (extra) features
The ability to check for multiple product IDs in the shopping cart
The custom field is only added if a certain product id is in the shopping cart
The possibility to check out if the custom field is not present (product ID is NOT in cart)
No possibility to checkout as long as the value 'Y' is not selected from the custom select menu (Product ID is IN cart)
Explanation via comment tags added in the code
// Add custom 'select' field after checkout billing form (if product ID is in cart)
function action_woocommerce_after_checkout_billing_form( $checkout ) {
// Check if Product in Cart
// Multiple product IDs can be entered, separated by a comma
$product_in_cart = is_product_in_cart( array( 212, 30, 815 ) );
// True
if ( $product_in_cart ) {
$domain = 'woocommerce';
$default = 'Y';
woocommerce_form_field( '_my_field_name', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'label' => __( 'Market Place - Please Select Y to complete this order', $domain ),
'required' => true,
'options' => array(
'Y' => __( 'Y', $domain ),
'N' => __( 'N', $domain ),
),
'default' => $default,
), $checkout->get_value( '_my_field_name' ) );
}
}
add_action( 'woocommerce_after_checkout_billing_form', 'action_woocommerce_after_checkout_billing_form', 10, 1 );
// Function to check if a certain product ID is in cart
function is_product_in_cart( $targeted_ids ) {
// Flag no product in cart
$flag = false;
// WC Cart NOT null
if ( ! is_null( WC()->cart ) ) {
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
// Check cart item for defined product Ids
if ( in_array( $cart_item['product_id'], $targeted_ids ) ) {
// Product is in cart
$flag = true;
// Break loop
break;
}
}
}
return $flag;
}
// Custom checkout 'select' field validation
function action_woocommerce_checkout_process() {
// Isset
if ( isset( $_POST['_my_field_name'] ) ) {
$domain = 'woocommerce';
$my_field_name = $_POST['_my_field_name'];
// Empty
if ( empty ( $my_field_name ) ) {
wc_add_notice( __( 'Please Select Y to complete this order', $domain ), 'error' );
}
// NOT empty but value is 'N'
if ( ! empty ( $my_field_name ) && $my_field_name == 'N' ) {
wc_add_notice( __( 'Please Select Y to complete this order', $domain ), 'error' );
}
}
}
add_action( 'woocommerce_checkout_process', 'action_woocommerce_checkout_process', 10, 0 );
// Save custom checkout 'select' field
function action_woocommerce_checkout_create_order( $order, $data ) {
// Isset
if ( isset( $_POST['_my_field_name'] ) ) {
$my_field_name = $_POST['_my_field_name'];
// NOT empty & equal to 'Y'
if ( ! empty( $my_field_name ) && $my_field_name == 'Y' ) {
$order->update_meta_data( '_my_field_name', sanitize_text_field( $my_field_name ) );
}
}
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );
// Display the custom 'select' field value on admin order pages after billing adress
function action_woocommerce_admin_order_data_after_billing_address( $order ) {
$domain = 'woocommerce';
// Get meta
$my_field_name = $order->get_meta( '_my_field_name' );
// NOT empty
if ( ! empty ( $my_field_name ) ) {
echo '<p><strong>' . __( 'Delivery type', $domain ) . ':</strong> ' . $order->get_meta( '_my_field_name' ) . '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'action_woocommerce_admin_order_data_after_billing_address', 10, 1 );
// Display the custom 'select' field value on 'order received' and 'order view' pages (frontend)
function action_woocommerce_order_details_after_order_table( $order ) {
$domain = 'woocommerce';
// Get meta
$my_field_name = $order->get_meta( '_my_field_name' );
// NOT empty
if ( ! empty ( $my_field_name ) ) {
echo '<p><strong>' . __( 'Delivery type', $domain ) . ':</strong> ' . $order->get_meta( '_my_field_name' ) . '</p>';
}
}
add_action( 'woocommerce_order_details_after_order_table', 'action_woocommerce_order_details_after_order_table', 10, 1 );

Mandatory custom radio button choice on Woocommerce checkout

I've got this custom code working to add a couple of radio buttons into the checkout:
add_action( 'woocommerce_review_order_before_payment', 'display_extra_fields_after_billing_address' , 10, 1 );
function display_extra_fields_after_billing_address () { ?>
<h3 class="delivery-options-heading">Delivery Options <sup>*</sup></h3>
<div class="delivery-options">
<p><input type="radio" name="delivery_option" value="Have the courier leave a card." required /> Have the courier leave a card.</p>
<p><input type="radio" name="delivery_option" value="Leave the consignment without a signature." required /> Leave the consignment without a signature.</p>
</div>
<?php
}
add_action( 'woocommerce_checkout_update_order_meta', 'add_delivery_option_to_order' , 10, 1);
function add_delivery_option_to_order ( $order_id ) {
if ( isset( $_POST ['delivery_option'] ) && '' != $_POST ['delivery_option'] ) {
add_post_meta( $order_id, '_delivery_option', sanitize_text_field( $_POST ['delivery_option'] ) );
}
}
add_filter( 'woocommerce_email_order_meta_fields', 'add_delivery_option_to_emails' , 10, 3 );
function add_delivery_option_to_emails ( $fields, $sent_to_admin, $order ) {
if( version_compare( get_option( 'woocommerce_version' ), '3.0.0', ">=" ) ) {
$order_id = $order->get_id();
} else {
$order_id = $order->id;
}
$delivery_option = get_post_meta( $order_id, '_delivery_option', true );
if ( '' != $delivery_option ) {
$fields[ 'Delivery Date' ] = array(
'label' => __( 'Delivery Option', 'delivery_option' ),
'value' => $delivery_option,
);
}
return $fields;
}
Every part of this works fine except for the required attributes on the radio buttons, letting the user checkout without making a choice, which is not ideal. For some reason the required attributes are being ignored.
How can I force the user to select one of the radio buttons before checking out?
Please add this validation hook along with your code that will validate your option on checkout
function action_woocommerce_after_checkout_validation( $data, $errors ) {
if( !isset( $data['delivery_option'] ) || empty( $data['delivery_option'] ) ) :
$errors->add( 'required-field', __( 'No delivery option has been selected. Please choose delivery option.', 'woocommerce' ) );
endif; //Endif
}
// add the action
add_action( 'woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );
This was the solution, slightly different to what Krunal Prajapati suggested. The only difference is the second line:
function action_woocommerce_after_checkout_validation( $data, $errors ) {
if ( empty( $_POST['delivery_option'] ) ) :
$errors->add( 'required-field', __( 'No delivery option has been selected. Please choose delivery option.', 'woocommerce' ) );
endif; //Endif
}
// add the action
add_action( 'woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );

Woocommerce - Calculate Exta Fee Based on Amount of People

I've added in a function for a custom field on the product general options:
// Add Custom Field to Product under General
function create_extra_fee_field() {
$args = array(
'id' => 'park_fee',
'label' => __( 'Natl Park Entrance Fee', 'tranq-lsx-child' ),
'class' => 'tranq-custom-field',
'desc_tip' => true,
'description' => __( 'This sets the Fee that will be added to the car.', 'tranq-lsx-child' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'create_extra_fee_field' );
// Save Custom Field Data
function save_extra_fee_field( $post_id ) {
$product = wc_get_product( $post_id );
$title = isset( $_POST['park_fee'] ) ? $_POST['park_fee'] : '';
$product->update_meta_data( 'park_fee', sanitize_text_field( $title ) );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'save_extra_fee_field' );
I would like to add this as an extra fee to the Cart Totals which multiplied based on the amount of Person/People that were selected from the Woocommerce Bookings.
Something like this:
// Calculate Extra Fee Based on Amount of People.
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
function add_custom_fees( WC_Cart $cart ){
$park_fee = get_post_meta($item['product_id'] , 'park_fee', true);
foreach( $cart->get_cart() as $item ){
$fees += $item[ 'park_fee' ] * 14706;
}
if( $fees != 0 ){
$cart->add_fee( 'Park Fee', $fees);
}
}
How do I go about in achieving this? Any Links to a walkthrough would be greatly appreciated.
I've added this and it seems to work:
// Add Custom Field to Cart Totals
function woo_add_cart_fee() {
global $woocommerce;
foreach( WC()->cart->get_cart() as $cart_item ){
// Get the WC_Product object (instance)
$product = $cart_item['data'];
$product_id = $product->get_id(); // get the product ID
$custom_field_value = get_post_meta( $product->get_id(), 'park_fee', true );
$person = array_sum( $cart_item['booking']['_persons'] );
}
$additional_fee_name = "Natl Park Entrance Fee";
$extra_fee = $custom_field_value * $person;
$addedFee = false;
// first check to make sure it isn’t already there
foreach ( $woocommerce->cart->get_fees() as $_fee )
{
if ($_fee->id == sanitize_title($additional_fee_name) )
{
$_fee->amount = (float) esc_attr( $extra_fee );
}
}
if (!$addedFee)
{
$woocommerce->cart->add_fee( __($additional_fee_name, "woocommerce"),
$extra_fee, $additional_fee_taxable );
}
}
add_action( "woocommerce_before_calculate_totals", "woo_add_cart_fee" );

Resources