Programmatically created WooCommerce order have no tax for new users

♀尐吖头ヾ 提交于 2021-02-15 06:50:13

问题


Im using Gravity forms to create an WooCommerce order programmatically.

If an email added to the form already exists, it takes the shipping and billing from the users account. This works and it adds the VAT correctly.

For a user that is not logged in, they add name, email, phone and country to the form, and the user is created automatically. The order is created, and the user is added. But in this case, the AT is not added and I have to manually recalculate the order for the VAT to be added.

How do I make sure the VAT is added when a user is programmatically created as well ?

code:

add_action( 'gform_after_submission_16', 'post_to_third_party', 10, 2 );
function post_to_third_party( $entry, $form ) {
    global $woocommerce;
    var_dump($entry);

   
    $product_id = rgar( $entry, '21' );
 

    $address = array(
      'first_name' => rgar( $entry, '20.3' ),
      'last_name'  => rgar( $entry, '20.6' ),
      'email'      => rgar( $entry, '10' ),
      'phone'      => rgar( $entry, '16' ),
      'address_1'  => rgar( $entry, '24.1' ),
      'address_2'  => rgar( $entry, '24.2' ),
      'city'       => rgar( $entry, '24.3' ),
      'state'      => rgar( $entry, '24.4' ),
      'postcode'   => rgar( $entry, '24.5' ),
      'country'    => rgar( $entry, '24.6' ),
    );

    
    $order = wc_create_order();
    $order->add_product( wc_get_product($product_id), 1); 
    $order->set_address( $address, 'billing' );  
    $country  = rgar( $entry, '24.6' );
    $username = rgar( $entry, '20.3' ); 
    $user_email = rgar( $entry, '10' );   
    
    $user_id = username_exists( $username );
    if ( !$user_id and email_exists($user_email) == false ) {
    $random_password = wp_generate_password( $length=12, $include_standard_special_chars=false );
    $user_id = wp_create_user( $username, $random_password, $user_email );    
    } else {
    $random_password = __('User already exists.  Password inherited.'); 
    $user = get_user_by( 'ID', $user_id );
    $firstname = get_user_meta( $user_id, 'billing_first_name', true );
    $lastname = get_user_meta( $user_id, 'billing_last_name', true );
    $address_1 = get_user_meta( $user_id, 'billing_address_1', true );
    $address_2 = get_user_meta( $user_id, 'billing_address_2', true );
    $city      = get_user_meta( $user_id, 'billing_city', true );
    $postcode  = get_user_meta( $user_id, 'billing_postcode', true );
    $country   = get_user_meta( $user_id, 'billing_country', true );
    $state     = get_user_meta( $user_id, 'billing_state', true );
    
    $firstname_ship = get_user_meta( $user_id, 'shipping_first_name', true );
    $lastname_ship = get_user_meta( $user_id, 'shipping_last_name', true );
    $address_1_ship = get_user_meta( $user_id, 'shipping_address_1', true );
    $address_2_ship = get_user_meta( $user_id, 'shipping_address_2', true );
    $city__ship  = get_user_meta( $user_id, 'shipping_city', true );
    $postcode_ship  = get_user_meta( $user_id, 'shipping_postcode', true );
    $country_ship   = get_user_meta( $user_id, 'shipping_country', true );
    $state_ship     = get_user_meta( $user_id, 'shipping_state', true );

    $address2         = array(
        'first_name' => $firstname, 
        'last_name'  => $lastname, 
        'address_1'  => $address_1,
        'address_2'  => $address_2,
        'city'       => $city,
        'state'      => $state,
        'postcode'   => $postcode,
        'country'    => $country,
    );
        $address3         = array(
        'first_name' => $firstname_ship, 
        'last_name'  => $lastname_ship,    
        'address_1'  => $address_1_ship,
        'address_2'  => $address_2_ship,
        'city'       => $city_ship,
        'state'      => $state_ship,
        'postcode'   => $postcode_ship,
        'country'    => $country_ship,
    );
    
    $order->set_address( $address2, 'billing' );
    $order->set_address( $address3, 'shipping' );
       
    }
    $order->set_customer_id( $user_id );
    $note = rgar( $entry, '5' ); ;
    $order->add_order_note( $note );
    $order->set_customer_note( $note );
    $emails = WC()->mailer()->get_emails();
    $emails['WC_Email_Customer_New_Account']->trigger( $user_id, $random_password, true );
    $order->calculate_totals();   
    $order->update_status('autoquote', TRUE);  
    $order->save();

}

Edit:

Seems like my new users are not correct created, they are missing name, phone and country. I added

wp_update_user([
    'ID' => $user_id,
     'first_name' => rgar( $entry, '20.3' ),
     'last_name'  => rgar( $entry, '20.6' ),
     'phone'      => rgar( $entry, '16' ),
     'country'  => rgar( $entry, '24.6' )
    ]); 

after $user_id = wp_create_user( $username, $random_password, $user_email );

And this sets the name correct on the user, but is still missing phone and country.


回答1:


Updated

I have revisited your code completely as there was different missing things and some mistakes. But I can't really test the code as this is related to a Gform plugin and custom form (not reproducible with the provided code and information):

add_action( 'gform_after_submission_16', 'post_to_third_party', 10, 2 );
function post_to_third_party( $entry, $form ) {
    // var_dump($entry);

    $order      = wc_create_order();
    $username   = rgar( $entry, '20.3' );
    $user_id    = username_exists( $username );

    // 1. User doesn't exist - Create it - send email - set address and define
    if ( ! $user_id && $user_id == false ) {
        $email      = rgar( $entry, '10' );
        $password   = wp_generate_password( 12, false );
        $first_name = rgar( $entry, '20.3' )
        $last_name  = rgar( $entry, '20.6' )
        
        $user_data = array(
            'user_login' => $username,
            'user_pass'  => $password,
            'user_email' => $email,
            'first_name' => $first_name,
            'last_name'  => $last_name,
            'role'       => 'customer',
        );

        $user_id  = wp_insert_user( $user_data );

        $address  = array(
          'first_name' => $first_name,
          'last_name'  => $last_name,
          'email'      => $email,
          'phone'      => rgar( $entry, '16' ),
          'address_1'  => rgar( $entry, '24.1' ),
          'address_2'  => rgar( $entry, '24.2' ),
          'city'       => rgar( $entry, '24.3' ),
          'state'      => rgar( $entry, '24.4' ),
          'postcode'   => rgar( $entry, '24.5' ),
          'country'    => rgar( $entry, '24.6' ),
        );

         
        // Update Billing and shipping user data
        foreach( $address as $key => $value ) {
            update_user_meta( $user_id, 'billing_' . $key, $value ); // Billing user data

            if( ! in array( $key, array('phone', 'email') ) ) {
               update_user_meta( $user_id, 'shipping_' . $key, $value ); // Shipping user data
            }
        }

        // Send Customer new account notification
        WC()->mailer()->get_emails()['WC_Email_Customer_New_Account']->trigger( $user_id, $password, true );

        $order->set_address( $address, 'billing' ); // set billing addresses fields

        unset( $address['phone'], $address['email'] ); // removing email and phone from array (for shipping)

        $order->set_address( $address, 'shipping' ); // set shipping addresses fields

        // For calculating taxes on items
        $calculate_taxes_for = array(
            'country'  => $address['country'],
            'state'    => $address['state'],
            'postcode' => $address['postcode'],
            'city'     => $address['city'],
        );

    }
    // 2. User exist
    else {
        $user = get_user_by( 'ID', $user_id ); // Get the WP_User Object

        $billing_address = array(
            'first_name' => $user->billing_first_name,
            'last_name'  => $user->billing_last_name,
            'email'      => $user->billing_email,
            'phone'      => $user->billing_phone,
            'address_1'  => $user->billing_address_1,
            'address_2'  => $user->billing_address_2,
            'city'       => $user->billing_city,
            'state'      => $user->billing_postcode,
            'postcode'   => $user->billing_country,
            'country'    => $user->billing_state,
        );

        $shipping_address = array(
            'first_name' => $user->shipping_first_name,
            'last_name'  => $user->shipping_last_name,
            'address_1'  => $user->shipping_address_1,
            'address_2'  => $user->shipping_address_2,
            'city'       => $user->shipping_city,
            'state'      => $user->shipping_postcode,
            'postcode'   => $user->shipping_country,
            'country'    => $user->shipping_state,
        );

        $order->set_address( $billing_address, 'billing' );
        $order->set_address( $shipping_address, 'shipping' );

        // For calculating taxes on items
        $calculate_taxes_for = array(
            'country'  => ! empty($shipping_address['country']) ? $shipping_address['country'] : $billing_address['country'],
            'state'    => ! empty($shipping_address['state']) ? $shipping_address['state'] : $billing_address['state'],
            'postcode' => ! empty($shipping_address['postcode']) ? $shipping_address['postcode'] : $billing_address['postcode'],
            'city'     => ! empty($shipping_address['city']) ? $shipping_address['city'] : $billing_address['city'],
        );

    }
    $order->set_customer_id( $user_id );

    $order->set_currency( get_woocommerce_currency() );
    $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );

    $product    = wc_get_product( rgar( $entry, '21' ) );
    
    $item_id    = $order->add_product( $product, 1 );
    $line_item  = $order->get_item( $item_id, false ); // Get the WC_Order_Item_Product Object instance from the Item Id
    $line_item->calculate_taxes($calculate_taxes_for); // <== Calculating taxes
    $line_item->save(); // Save data to WC_Order_Item_Product Object

    $note = rgar( $entry, '5' );
    $order->add_order_note( $note );
    $order->set_customer_note( $note );

    $order->calculate_totals();
    $order->update_status('autoquote', true); // $order->save() is already included with update_status() method
}

Code goes in functions.php file of the active child theme (or active theme). It should works.

Based on: Create an order programmatically with line items in Woocommerce



来源:https://stackoverflow.com/questions/64662176/programmatically-created-woocommerce-order-have-no-tax-for-new-users

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!