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
2
Answers
You need to calculate
Advance Payment
before display. you can usewoocommerce_admin_order_item_headers
action hook.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.