/** * Create or update a line item * * @since 2.2 * @param \WC_Order $order * @param array $item line item data * @param string $action 'create' to add line item or 'update' to update it * @throws WC_API_Exception invalid data, server error */ protected function set_line_item($order, $item, $action) { $creating = 'create' === $action; // product is always required if (!isset($item['product_id']) && !isset($item['sku'])) { throw new WC_API_Exception('woocommerce_api_invalid_product_id', __('Product ID or SKU is required', 'woocommerce'), 400); } // when updating, ensure product ID provided matches if ('update' === $action) { $item_product_id = wc_get_order_item_meta($item['id'], '_product_id'); $item_variation_id = wc_get_order_item_meta($item['id'], '_variation_id'); if ($item['product_id'] != $item_product_id && $item['product_id'] != $item_variation_id) { throw new WC_API_Exception('woocommerce_api_invalid_product_id', __('Product ID provided does not match this line item', 'woocommerce'), 400); } } if (isset($item['product_id'])) { $product_id = $item['product_id']; } elseif (isset($item['sku'])) { $product_id = wc_get_product_id_by_sku($item['sku']); } // variations must each have a key & value $variation_id = 0; if (isset($item['variations']) && is_array($item['variations'])) { foreach ($item['variations'] as $key => $value) { if (!$key || !$value) { throw new WC_API_Exception('woocommerce_api_invalid_product_variation', __('The product variation is invalid', 'woocommerce'), 400); } } $variation_id = $this->get_variation_id(wc_get_product($product_id), $item['variations']); } $product = wc_get_product($variation_id ? $variation_id : $product_id); // must be a valid WC_Product if (!is_object($product)) { throw new WC_API_Exception('woocommerce_api_invalid_product', __('Product is invalid', 'woocommerce'), 400); } // quantity must be positive float if (isset($item['quantity']) && floatval($item['quantity']) <= 0) { throw new WC_API_Exception('woocommerce_api_invalid_product_quantity', __('Product quantity must be a positive float', 'woocommerce'), 400); } // quantity is required when creating if ($creating && !isset($item['quantity'])) { throw new WC_API_Exception('woocommerce_api_invalid_product_quantity', __('Product quantity is required', 'woocommerce'), 400); } if ($creating) { $item = new WC_Order_Item_Product(); } else { $item = new WC_Order_Item_Product($item['id']); } $item->set_product($product); $item->set_order_id($order->id); if (isset($item['quantity'])) { $item->set_quantity($item['quantity']); } if (isset($item['total'])) { $item->set_total(floatval($item['total'])); } if (isset($item['total_tax'])) { $item->set_total_tax(floatval($item['total_tax'])); } if (isset($item['subtotal'])) { $item->set_subtotal(floatval($item['subtotal'])); } if (isset($item['subtotal_tax'])) { $item->set_subtotal_tax(floatval($item['subtotal_tax'])); } if ($variation_id) { $item->set_variation_id($variation_id); $item->set_variation($item['variations']); } $item_id = $item->save(); if (!$item_id) { throw new WC_API_Exception('woocommerce_cannot_create_line_item', __('Cannot create line item, try again', 'woocommerce'), 500); } }
/** * Create or update a line item. * * @param array $posted Line item data. * @param string $action 'create' to add line item or 'update' to update it. * @throws WC_REST_Exception Invalid data, server error. */ protected function prepare_line_items($posted, $action = 'create') { $item = new WC_Order_Item_Product(!empty($posted['id']) ? $posted['id'] : ''); $product = wc_get_product($this->get_product_id($posted)); if ($product !== $item->get_product()) { $item->set_product($product); if ('create' === $action) { $total = $product->get_price() * (isset($posted['quantity']) ? $posted['quantity'] : 1); $item->set_total($total); $item->set_subtotal($total); } } $this->maybe_set_item_props($item, array('name', 'quantity', 'total', 'subtotal', 'tax_class'), $posted); return $item; }