/**
  * Create order.
  *
  * @param WP_REST_Request $request Full details about the request.
  * @return int|WP_Error
  */
 protected function create_order($request)
 {
     wc_transaction_query('start');
     try {
         // Make sure customer exists.
         if (0 !== $request['customer_id'] && false === get_user_by('id', $request['customer_id'])) {
             throw new WC_REST_Exception('woocommerce_rest_invalid_customer_id', __('Customer ID is invalid.', 'woocommerce'), 400);
         }
         $data = $this->prepare_item_for_database($request);
         if (is_wp_error($data)) {
             return $data;
         }
         $data->created_via = 'rest-api';
         $order = $this->create_base_order((array) $data);
         if (is_wp_error($order)) {
             throw new WC_REST_Exception('woocommerce_rest_cannot_create_order', sprintf(__('Cannot create order: %s.', 'woocommerce'), implode(', ', $order->get_error_messages())), 400);
         }
         // Set addresses.
         if (is_array($request['billing'])) {
             $this->update_address($order, $request['billing'], 'billing');
         }
         if (is_array($request['shipping'])) {
             $this->update_address($order, $request['shipping'], 'shipping');
         }
         // Set currency.
         update_post_meta($order->id, '_order_currency', $request['currency']);
         // Set lines.
         $lines = array('line_item' => 'line_items', 'shipping' => 'shipping_lines', 'fee' => 'fee_lines', 'coupon' => 'coupon_lines');
         foreach ($lines as $line_type => $line) {
             if (is_array($request[$line])) {
                 foreach ($request[$line] as $item) {
                     $set_item = 'set_' . $line_type;
                     $this->{$set_item}($order, $item, 'create');
                 }
             }
         }
         // Calculate totals and set them.
         $order->calculate_totals();
         // Set payment method.
         if (!empty($request['payment_method'])) {
             update_post_meta($order->id, '_payment_method', $request['payment_method']);
         }
         if (!empty($request['payment_method_title'])) {
             update_post_meta($order->id, '_payment_method_title', $request['payment_method']);
         }
         if (true === $request['set_paid']) {
             $order->payment_complete($request['transaction_id']);
         }
         // Set meta data.
         if (!empty($request['meta_data']) && is_array($request['meta_data'])) {
             $this->update_meta_data($order->id, $request['meta_data']);
         }
         wc_transaction_query('commit');
         return $order->id;
     } catch (WC_REST_Exception $e) {
         wc_transaction_query('rollback');
         return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
     }
 }
 /**
  * Create an order
  *
  * @since 2.2
  * @param array $data raw order data
  * @return array
  */
 public function create_order($data)
 {
     global $wpdb;
     wc_transaction_query('start');
     try {
         if (!isset($data['order'])) {
             throw new WC_API_Exception('woocommerce_api_missing_order_data', sprintf(__('No %1$s data specified to create %1$s', 'woocommerce'), 'order'), 400);
         }
         $data = $data['order'];
         // permission check
         if (!current_user_can('publish_shop_orders')) {
             throw new WC_API_Exception('woocommerce_api_user_cannot_create_order', __('You do not have permission to create orders', 'woocommerce'), 401);
         }
         $data = apply_filters('woocommerce_api_create_order_data', $data, $this);
         // default order args, note that status is checked for validity in wc_create_order()
         $default_order_args = array('status' => isset($data['status']) ? $data['status'] : '', 'customer_note' => isset($data['note']) ? $data['note'] : null);
         // if creating order for existing customer
         if (!empty($data['customer_id'])) {
             // make sure customer exists
             if (false === get_user_by('id', $data['customer_id'])) {
                 throw new WC_API_Exception('woocommerce_api_invalid_customer_id', __('Customer ID is invalid', 'woocommerce'), 400);
             }
             $default_order_args['customer_id'] = $data['customer_id'];
         }
         // create the pending order
         $order = $this->create_base_order($default_order_args, $data);
         if (is_wp_error($order)) {
             throw new WC_API_Exception('woocommerce_api_cannot_create_order', sprintf(__('Cannot create order: %s', 'woocommerce'), implode(', ', $order->get_error_messages())), 400);
         }
         // billing/shipping addresses
         $this->set_order_addresses($order, $data);
         $lines = array('line_item' => 'line_items', 'shipping' => 'shipping_lines', 'fee' => 'fee_lines', 'coupon' => 'coupon_lines');
         foreach ($lines as $line_type => $line) {
             if (isset($data[$line]) && is_array($data[$line])) {
                 $set_item = "set_{$line_type}";
                 foreach ($data[$line] as $item) {
                     $this->{$set_item}($order, $item, 'create');
                 }
             }
         }
         // calculate totals and set them
         $order->calculate_totals();
         // payment method (and payment_complete() if `paid` == true)
         if (isset($data['payment_details']) && is_array($data['payment_details'])) {
             // method ID & title are required
             if (empty($data['payment_details']['method_id']) || empty($data['payment_details']['method_title'])) {
                 throw new WC_API_Exception('woocommerce_invalid_payment_details', __('Payment method ID and title are required', 'woocommerce'), 400);
             }
             update_post_meta($order->get_id(), '_payment_method', $data['payment_details']['method_id']);
             update_post_meta($order->get_id(), '_payment_method_title', $data['payment_details']['method_title']);
             // mark as paid if set
             if (isset($data['payment_details']['paid']) && true === $data['payment_details']['paid']) {
                 $order->payment_complete(isset($data['payment_details']['transaction_id']) ? $data['payment_details']['transaction_id'] : '');
             }
         }
         // set order currency
         if (isset($data['currency'])) {
             if (!array_key_exists($data['currency'], get_woocommerce_currencies())) {
                 throw new WC_API_Exception('woocommerce_invalid_order_currency', __('Provided order currency is invalid', 'woocommerce'), 400);
             }
             update_post_meta($order->get_id(), '_order_currency', $data['currency']);
         }
         // set order meta
         if (isset($data['order_meta']) && is_array($data['order_meta'])) {
             $this->set_order_meta($order->get_id(), $data['order_meta']);
         }
         // HTTP 201 Created
         $this->server->send_status(201);
         wc_delete_shop_order_transients($order->get_id());
         do_action('woocommerce_api_create_order', $order->get_id(), $data, $this);
         wc_transaction_query('commit');
         return $this->get_order($order->get_id());
     } catch (WC_Data_Exception $e) {
         wc_transaction_query('rollback');
         return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => 400));
     } catch (WC_API_Exception $e) {
         wc_transaction_query('rollback');
         return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode()));
     }
 }
 /**
  * Create an order. Error codes:
  * 		520 - Cannot insert order into the database.
  * 		521 - Cannot get order after creation.
  * 		522 - Cannot update order.
  * 		525 - Cannot create line item.
  * 		526 - Cannot create fee item.
  * 		527 - Cannot create shipping item.
  * 		528 - Cannot create tax item.
  * 		529 - Cannot create coupon item.
  * @access public
  * @throws Exception
  * @return int|WP_ERROR
  */
 public function create_order()
 {
     global $wpdb;
     // Give plugins the opportunity to create an order themselves
     if ($order_id = apply_filters('woocommerce_create_order', null, $this)) {
         return $order_id;
     }
     try {
         // Start transaction if available
         wc_transaction_query('start');
         $order_data = array('status' => apply_filters('woocommerce_default_order_status', 'pending'), 'customer_id' => $this->customer_id, 'customer_note' => isset($this->posted['order_comments']) ? $this->posted['order_comments'] : '', 'cart_hash' => md5(json_encode(WC()->cart->get_cart_for_session()) . WC()->cart->total), 'created_via' => 'checkout');
         // Insert or update the post data
         $order_id = absint(WC()->session->order_awaiting_payment);
         /**
          * If there is an order pending payment, we can resume it here so
          * long as it has not changed. If the order has changed, i.e.
          * different items or cost, create a new order. We use a hash to
          * detect changes which is based on cart items + order total.
          */
         if ($order_id && $order_data['cart_hash'] === get_post_meta($order_id, '_cart_hash', true) && ($order = wc_get_order($order_id)) && $order->has_status(array('pending', 'failed'))) {
             $order_data['order_id'] = $order_id;
             $order = wc_update_order($order_data);
             if (is_wp_error($order)) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 522));
             } else {
                 $order->remove_order_items();
                 do_action('woocommerce_resume_order', $order_id);
             }
         } else {
             $order = wc_create_order($order_data);
             if (is_wp_error($order)) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 520));
             } elseif (false === $order) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 521));
             } else {
                 $order_id = $order->id;
                 do_action('woocommerce_new_order', $order_id);
             }
         }
         // Store the line items to the new/resumed order
         foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
             $item_id = $order->add_product($values['data'], $values['quantity'], array('variation' => $values['variation'], 'totals' => array('subtotal' => $values['line_subtotal'], 'subtotal_tax' => $values['line_subtotal_tax'], 'total' => $values['line_total'], 'tax' => $values['line_tax'], 'tax_data' => $values['line_tax_data'])));
             if (!$item_id) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 525));
             }
             // Allow plugins to add order item meta
             do_action('woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key);
         }
         // Store fees
         foreach (WC()->cart->get_fees() as $fee_key => $fee) {
             $item_id = $order->add_fee($fee);
             if (!$item_id) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 526));
             }
             // Allow plugins to add order item meta to fees
             do_action('woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key);
         }
         // Store shipping for all packages
         foreach (WC()->shipping->get_packages() as $package_key => $package) {
             if (isset($package['rates'][$this->shipping_methods[$package_key]])) {
                 $item_id = $order->add_shipping($package['rates'][$this->shipping_methods[$package_key]]);
                 if (!$item_id) {
                     throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 527));
                 }
                 // Allows plugins to add order item meta to shipping
                 do_action('woocommerce_add_shipping_order_item', $order_id, $item_id, $package_key);
             }
         }
         // Store tax rows
         foreach (array_keys(WC()->cart->taxes + WC()->cart->shipping_taxes) as $tax_rate_id) {
             if ($tax_rate_id && !$order->add_tax($tax_rate_id, WC()->cart->get_tax_amount($tax_rate_id), WC()->cart->get_shipping_tax_amount($tax_rate_id)) && apply_filters('woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated') !== $tax_rate_id) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 528));
             }
         }
         // Store coupons
         foreach (WC()->cart->get_coupons() as $code => $coupon) {
             if (!$order->add_coupon($code, WC()->cart->get_coupon_discount_amount($code), WC()->cart->get_coupon_discount_tax_amount($code))) {
                 throw new Exception(sprintf(__('Error %d: Unable to create order. Please try again.', 'woocommerce'), 529));
             }
         }
         // Billing address
         $billing_address = array();
         if ($this->checkout_fields['billing']) {
             foreach (array_keys($this->checkout_fields['billing']) as $field) {
                 $field_name = str_replace('billing_', '', $field);
                 $billing_address[$field_name] = $this->get_posted_address_data($field_name);
             }
         }
         // Shipping address.
         $shipping_address = array();
         if ($this->checkout_fields['shipping']) {
             foreach (array_keys($this->checkout_fields['shipping']) as $field) {
                 $field_name = str_replace('shipping_', '', $field);
                 $shipping_address[$field_name] = $this->get_posted_address_data($field_name, 'shipping');
             }
         }
         $order->set_address($billing_address, 'billing');
         $order->set_address($shipping_address, 'shipping');
         $order->set_payment_method($this->payment_method);
         $order->set_total(WC()->cart->shipping_total, 'shipping');
         $order->set_total(WC()->cart->get_cart_discount_total(), 'cart_discount');
         $order->set_total(WC()->cart->get_cart_discount_tax_total(), 'cart_discount_tax');
         $order->set_total(WC()->cart->tax_total, 'tax');
         $order->set_total(WC()->cart->shipping_tax_total, 'shipping_tax');
         $order->set_total(WC()->cart->total);
         // Update user meta
         if ($this->customer_id) {
             if (apply_filters('woocommerce_checkout_update_customer_data', true, $this)) {
                 foreach ($billing_address as $key => $value) {
                     update_user_meta($this->customer_id, 'billing_' . $key, $value);
                 }
                 if (WC()->cart->needs_shipping()) {
                     foreach ($shipping_address as $key => $value) {
                         update_user_meta($this->customer_id, 'shipping_' . $key, $value);
                     }
                 }
             }
             do_action('woocommerce_checkout_update_user_meta', $this->customer_id, $this->posted);
         }
         // Let plugins add meta
         do_action('woocommerce_checkout_update_order_meta', $order_id, $this->posted);
         // If we got here, the order was created without problems!
         wc_transaction_query('commit');
     } catch (Exception $e) {
         // There was an error adding order data!
         wc_transaction_query('rollback');
         return new WP_Error('checkout-error', $e->getMessage());
     }
     return $order_id;
 }
 /**
  * Create an order.
  *
  * ## OPTIONS
  *
  * [--<field>=<value>]
  * : Associative args for the new order.
  *
  * [--porcelain]
  * : Outputs just the new order id.
  *
  * ## AVAILABLE FIELDS
  *
  * Required fields:
  *
  * * customer_id
  *
  * Optional fields:
  *
  * * status
  * * note
  * * currency
  * * order_meta
  *
  * Payment detail fields:
  *
  * * payment_details.method_id
  * * payment_details.method_title
  * * payment_details.paid
  *
  * Billing address fields:
  *
  * * billing_address.first_name
  * * billing_address.last_name
  * * billing_address.company
  * * billing_address.address_1
  * * billing_address.address_2
  * * billing_address.city
  * * billing_address.state
  * * billing_address.postcode
  * * billing_address.country
  * * billing_address.email
  * * billing_address.phone
  *
  * Shipping address fields:
  *
  * * shipping_address.first_name
  * * shipping_address.last_name
  * * shipping_address.company
  * * shipping_address.address_1
  * * shipping_address.address_2
  * * shipping_address.city
  * * shipping_address.state
  * * shipping_address.postcode
  * * shipping_address.country
  *
  * Line item fields (numeric array, started with index zero):
  *
  * * line_items.0.product_id
  * * line_items.0.quantity
  * * line_items.0.variations.pa_color
  *
  * For second line item: line_items.1.product_id and so on.
  *
  * Shipping line fields (numeric array, started with index zero):
  *
  * * shipping_lines.0.method_id
  * * shipping_lines.0.method_title
  * * shipping_lines.0.total
  *
  * For second shipping item: shipping_lines.1.method_id and so on.
  *
  * ## EXAMPLES
  *
  *     wp wc order create --customer_id=1 --status=pending ...
  *
  * @since  2.5.0
  */
 public function create($__, $assoc_args)
 {
     global $wpdb;
     wc_transaction_query('start');
     try {
         $porcelain = isset($assoc_args['porcelain']);
         unset($assoc_args['porcelain']);
         $data = apply_filters('woocommerce_cli_create_order_data', $this->unflatten_array($assoc_args));
         // default order args, note that status is checked for validity in wc_create_order()
         $default_order_args = array('status' => isset($data['status']) ? $data['status'] : '', 'customer_note' => isset($data['note']) ? $data['note'] : null);
         if (empty($data['customer_id'])) {
             throw new WC_CLI_Exception('woocommerce_cli_missing_customer_id', __('Missing customer_id field', 'woocommerce'));
         }
         // make sure customer exists
         if (false === get_user_by('id', $data['customer_id'])) {
             throw new WC_CLI_Exception('woocommerce_cli_invalid_customer_id', __('Customer ID is invalid', 'woocommerce'));
         }
         $default_order_args['customer_id'] = $data['customer_id'];
         // create the pending order
         $order = $this->create_base_order($default_order_args, $data);
         if (is_wp_error($order)) {
             throw new WC_CLI_Exception('woocommerce_cli_cannot_create_order', sprintf(__('Cannot create order: %s', 'woocommerce'), implode(', ', $order->get_error_messages())));
         }
         // billing/shipping addresses
         $this->set_order_addresses($order, $data);
         $lines = array('line_item' => 'line_items', 'shipping' => 'shipping_lines', 'fee' => 'fee_lines', 'coupon' => 'coupon_lines');
         foreach ($lines as $line_type => $line) {
             if (isset($data[$line]) && is_array($data[$line])) {
                 $set_item = "set_{$line_type}";
                 foreach ($data[$line] as $item) {
                     $this->{$set_item}($order, $item, 'create');
                 }
             }
         }
         // calculate totals and set them
         $order->calculate_totals();
         // payment method (and payment_complete() if `paid` == true)
         if (isset($data['payment_details']) && is_array($data['payment_details'])) {
             // method ID & title are required
             if (empty($data['payment_details']['method_id']) || empty($data['payment_details']['method_title'])) {
                 throw new WC_CLI_Exception('woocommerce_invalid_payment_details', __('Payment method ID and title are required', 'woocommerce'));
             }
             update_post_meta($order->id, '_payment_method', $data['payment_details']['method_id']);
             update_post_meta($order->id, '_payment_method_title', $data['payment_details']['method_title']);
             // Mark as paid if set.
             if (isset($data['payment_details']['paid']) && $this->is_true($data['payment_details']['paid'])) {
                 $order->payment_complete(isset($data['payment_details']['transaction_id']) ? $data['payment_details']['transaction_id'] : '');
             }
         }
         // Set order currency.
         if (isset($data['currency'])) {
             if (!array_key_exists($data['currency'], get_woocommerce_currencies())) {
                 throw new WC_CLI_Exception('woocommerce_invalid_order_currency', __('Provided order currency is invalid', 'woocommerce'));
             }
             update_post_meta($order->id, '_order_currency', $data['currency']);
         }
         // Set order meta.
         if (isset($data['order_meta']) && is_array($data['order_meta'])) {
             $this->set_order_meta($order->id, $data['order_meta']);
         }
         wc_delete_shop_order_transients($order->id);
         do_action('woocommerce_cli_create_order', $order->id, $data);
         wc_transaction_query('commit');
         if ($porcelain) {
             WP_CLI::line($order->id);
         } else {
             WP_CLI::success("Created order {$order->id}.");
         }
     } catch (WC_CLI_Exception $e) {
         wc_transaction_query('rollback');
         WP_CLI::error($e->getMessage());
     }
 }
 /**
  * Create an order. Error codes:
  * 		520 - Cannot insert order into the database.
  * 		521 - Cannot get order after creation.
  * 		522 - Cannot update order.
  * 		525 - Cannot create line item.
  * 		526 - Cannot create fee item.
  * 		527 - Cannot create shipping item.
  * 		528 - Cannot create tax item.
  * 		529 - Cannot create coupon item.
  * @throws Exception
  * @return int|WP_ERROR
  */
 public function create_order()
 {
     global $wpdb;
     // Give plugins the opportunity to create an order themselves
     if ($order_id = apply_filters('woocommerce_create_order', null, $this)) {
         return $order_id;
     }
     try {
         // Start transaction if available
         wc_transaction_query('start');
         // Insert or update the post data
         $order_id = absint(WC()->session->order_awaiting_payment);
         $cart_hash = md5(json_encode(wc_clean(WC()->cart->get_cart_for_session())) . WC()->cart->total);
         /**
          * If there is an order pending payment, we can resume it here so
          * long as it has not changed. If the order has changed, i.e.
          * different items or cost, create a new order. We use a hash to
          * detect changes which is based on cart items + order total.
          */
         if ($order_id && ($order = wc_get_order($order_id)) && $order->has_cart_hash($cart_hash) && $order->has_status(array('pending', 'failed'))) {
             // Action for 3rd parties.
             do_action('woocommerce_resume_order', $order_id);
             // Remove all items - we will re-add them later.
             $order->remove_order_items();
             /**
              * Not resuming - lets create a new order object.
              */
         } else {
             $order = new WC_Order();
         }
         $order->set_created_via('checkout');
         $order->set_cart_hash($cart_hash);
         $order->set_customer_id($this->customer_id);
         $order->set_currency(get_woocommerce_currency());
         $order->set_prices_include_tax('yes' === get_option('woocommerce_prices_include_tax'));
         $order->set_customer_ip_address(WC_Geolocation::get_ip_address());
         $order->set_customer_user_agent(wc_get_user_agent());
         $order->set_customer_note(isset($this->posted['order_comments']) ? $this->posted['order_comments'] : '');
         $order->set_payment_method($this->payment_method);
         $order->set_shipping_total(WC()->cart->shipping_total);
         $order->set_discount_total(WC()->cart->get_cart_discount_total());
         $order->set_discount_tax(WC()->cart->get_cart_discount_tax_total());
         $order->set_cart_tax(WC()->cart->tax_total);
         $order->set_shipping_tax(WC()->cart->shipping_tax_total);
         $order->set_total(WC()->cart->total);
         // Billing and shipping addresses
         if ($address_keys = array_merge(array_keys($this->checkout_fields['billing']), array_keys($this->checkout_fields['shipping']))) {
             foreach ($address_keys as $key) {
                 if (is_callable(array($order, "set_{$key}"))) {
                     $order->{"set_{$key}"}($this->get_posted_address_data(str_replace(array('billing_', 'shipping_'), '', $key), strstr($key, 'billing_') ? 'billing' : 'shipping'));
                 }
             }
         }
         // Add line items.
         foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
             $product = $values['data'];
             $item = new WC_Order_Item_Product(array('quantity' => $values['quantity'], 'name' => $product ? $product->get_title() : '', 'tax_class' => $product ? $product->get_tax_class() : '', 'product_id' => $product && isset($product->id) ? $product->id : 0, 'variation_id' => $product && isset($product->variation_id) ? $product->variation_id : 0, 'variation' => $values['variation'], 'subtotal' => $values['line_subtotal'], 'total' => $values['line_total'], 'subtotal_tax' => $values['line_subtotal_tax'], 'total_tax' => $values['line_tax'], 'taxes' => $values['line_tax_data']));
             $item->set_backorder_meta();
             // Set this to pass to legacy actions @todo remove in future release
             $item->legacy_values = $values;
             $item->legacy_cart_item_key = $cart_item_key;
             $order->add_item($item);
         }
         // Add fees
         foreach (WC()->cart->get_fees() as $fee_key => $fee) {
             $item = new WC_Order_Item_Fee(array('name' => $fee->name, 'tax_class' => $fee->taxable ? $fee->tax_class : 0, 'total' => $fee->amount, 'total_tax' => $fee->tax, 'taxes' => array('total' => $fee->tax_data)));
             // Set this to pass to legacy actions @todo remove in future release
             $item->legacy_fee = $fee;
             $item->legacy_fee_key = $fee_key;
             $order->add_item($item);
         }
         // Store shipping for all packages
         foreach (WC()->shipping->get_packages() as $package_key => $package) {
             if (isset($package['rates'][$this->shipping_methods[$package_key]])) {
                 $shipping_rate = $package['rates'][$this->shipping_methods[$package_key]];
                 $item = new WC_Order_Item_Shipping(array('method_title' => $shipping_rate->label, 'method_id' => $shipping_rate->id, 'total' => wc_format_decimal($shipping_rate->cost), 'taxes' => $shipping_rate->taxes, 'meta_data' => $shipping_rate->get_meta_data()));
                 // Set this to pass to legacy actions @todo remove in future release
                 $item->legacy_package_key = $package_key;
                 $order->add_item($item);
             }
         }
         // Store tax rows
         foreach (array_keys(WC()->cart->taxes + WC()->cart->shipping_taxes) as $tax_rate_id) {
             if ($tax_rate_id && apply_filters('woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated') !== $tax_rate_id) {
                 $order->add_item(new WC_Order_Item_Tax(array('rate_id' => $tax_rate_id, 'tax_total' => WC()->cart->get_tax_amount($tax_rate_id), 'shipping_tax_total' => WC()->cart->get_shipping_tax_amount($tax_rate_id), 'rate_code' => WC_Tax::get_rate_code($tax_rate_id), 'label' => WC_Tax::get_rate_label($tax_rate_id), 'compound' => WC_Tax::is_compound($tax_rate_id))));
             }
         }
         // Store coupons
         foreach (WC()->cart->get_coupons() as $code => $coupon) {
             $item = new WC_Order_Item_Coupon(array('code' => $code, 'discount' => WC()->cart->get_coupon_discount_amount($code), 'discount_tax' => WC()->cart->get_coupon_discount_tax_amount($code)));
             $order->add_item($item);
         }
         // Save the order
         $order_id = $order->save();
         // Update user meta
         $this->update_customer_data();
         // Let plugins add their own meta data
         do_action('woocommerce_checkout_update_order_meta', $order_id, $this->posted);
         // If we got here, the order was created without problems!
         wc_transaction_query('commit');
     } catch (Exception $e) {
         // There was an error adding order data!
         wc_transaction_query('rollback');
         return new WP_Error('checkout-error', $e->getMessage());
     }
     return $order_id;
 }
 /**
  * Process an order
  *
  * @since 3.0.0
  * @param mixed $data Parsed order data, ready for processing, compatible with
  *                    wc_create_order/wc_update_order
  * @param array $options Optional. Options
  * @param array $raw_headers Optional. Raw headers
  * @return int|null
  */
 protected function process_item($data, $options = array(), $raw_headers = array())
 {
     // if recalculate_totals is not provided, default to false
     $options = wp_parse_args($options, array('recalculate_totals' => false));
     $merging = $options['merge'] && isset($data['id']) && $data['id'];
     $dry_run = isset($options['dry_run']) && $options['dry_run'];
     wc_csv_import_suite()->log(__('> Processing order', 'woocommerce-csv-import-suite'));
     $order_identifier = $this->get_item_identifier($data);
     if (!$dry_run) {
         wc_transaction_query('start');
     }
     try {
         if ($merging) {
             wc_csv_import_suite()->log(sprintf(__('> Merging order %s.', 'woocommerce-csv-import-suite'), $order_identifier));
             if (!$dry_run) {
                 $order_id = $this->update_order($data['id'], $data, $options);
             }
         } else {
             // insert customer
             wc_csv_import_suite()->log(sprintf(__('> Inserting order %s', 'woocommerce-csv-import-suite'), esc_html($order_identifier)));
             if (!$dry_run) {
                 $order_id = $this->create_order($data, $options);
             }
         }
         // import failed
         if (!$dry_run && is_wp_error($order_id)) {
             $this->add_import_result('failed', $order_id->get_error_message());
             return null;
         }
         // TODO: is that OK to log and return as order_id in case of dry run?
         if ($dry_run) {
             $order_id = $merging ? $data['id'] : 9999;
         }
         if (!$dry_run) {
             wc_transaction_query('commit');
         }
     } catch (WC_CSV_Import_Suite_Import_Exception $e) {
         if (!$dry_run) {
             wc_transaction_query('rollback');
         }
         $this->add_import_result('failed', $e->getMessage());
         return null;
     }
     // no order identifier provided in CSV, use the order ID
     if (!$order_identifier) {
         $order_identifier = $order_id;
     }
     if ($merging) {
         wc_csv_import_suite()->log(sprintf(__('> Finished merging order %s.', 'woocommerce-csv-import-suite'), $order_identifier));
         $this->add_import_result('merged');
     } else {
         wc_csv_import_suite()->log(sprintf(__('> Finished importing order %s.', 'woocommerce-csv-import-suite'), $order_identifier));
         $this->add_import_result('inserted');
     }
     return $order_id;
 }