/**
* 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);
}
}