3

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.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Jerry
  • 1,069
  • 2
  • 13
  • 31
  • Hey, did you manage to add the EU VAT to the order? Could you help me out? https://stackoverflow.com/questions/72347253/woocommerce-programmatically-set-eu-vat-in-order – Jay Jun 01 '22 at 13:18

1 Answers1

4

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you - this will be helpful for me for settings this up a bit more nicely, and a few more things to include and test. Doesnt work fully as i want, this doesn't update the user meta for the new customer (no name, phone and country) on the new user so doesnt calculate VAT for me. – Jerry Nov 03 '20 at 20:33
  • I added name to the user data array, this sets it correct. Im still at missing piece with the phone number and country for the new user, since this doent seem to work in the Array ```$user_data = array( 'user_login' => $username, 'user_pass' => $password, 'user_email' => $email, 'role' => 'customer', 'country' => rgar( $entry, '24.6' ), 'phone' => rgar( $entry, '16' ), 'first_name' => rgar( $entry, '20.3' ), 'last_name' => rgar( $entry, '20.6' ), );``` – Jerry Nov 03 '20 at 20:57
  • @user3344734 See on your other question… I have answered. – LoicTheAztec Nov 03 '20 at 21:05
  • @LoicTheAztec Hey could you take a look at my similair question? I need to add EU VAT to the order but I can't get it to work... https://stackoverflow.com/questions/72347253/woocommerce-programmatically-set-eu-vat-in-order. Thanks – Jay Jun 01 '22 at 13:17