1
votes

I am trying to add a fee (discount) at checkout based on a users account balance. We end up with refunds in virtually every order and creating coupons is very tedious. I have created a custom user field where I can quickly set the refund amount as credit value that then gets applied at checkout on the following order.

So far everything is working except the fee appears when checkout loads and then disappears again. It works if I set a static amount but when setting the fee from a variable I get the behaviour above.

Add User custom field

add_action( 'show_user_profile', 'extra_user_profile_fields' );
add_action( 'edit_user_profile', 'extra_user_profile_fields' );

function extra_user_profile_fields( $user ) { ?>
    <h3><?php _e("FoodBox Info", "blank"); ?></h3>
    <table class="form-table">
    <tr>
    <th><label for="account-balance"><?php _e("Account Balance"); ?></label></th>
        <td>
            <input type="number" name="account-balance" id="account-balance" value="<?php echo esc_attr( get_the_author_meta( 'account-balance', $user->ID ) ); ?>" class="number" /><br />
            <span class="description"><?php _e("Credit balance ie -30"); ?></span>
        </td>
    </tr>
    </table>
<?php }

//save in db
add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );

function save_extra_user_profile_fields( $user_id ) {
    if ( !current_user_can( 'edit_user', $user_id ) ) { 
        return false; 
    }
    update_user_meta( $user_id, 'account-balance', $_POST['account-balance'] );
}

Get and apply the credit balance at checkout if user has one

//load at checkout
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount', 10, 1 );

function custom_discount( $user ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

        $discount =  esc_attr( get_the_author_meta( 'account-balance', $user->ID ) );

     if (get_the_author_meta( 'account-balance', $user->ID ) ){
        WC()->cart->add_fee('Credit', $discount, true);   
     }
}

It seems that perhaps as the shipping fee gets calculated the credit fee gets overwritten / reset but even if I disable shipping I get het same behaviour.

1

1 Answers

1
votes

The parameter passed to woocommerce_cart_calculate_fees is not $user but the $cart_object

function custom_discount( $cart_object ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $user_id = get_current_user_id();

    $discount = get_user_meta( $user_id, 'account-balance', true );

    // True
    if ( $discount ) {
        $cart_object->add_fee( 'Credit', $discount );  
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount', 10, 1 );