Automattic\WooCommerce\Admin\API\Reports\Products

DataStore::sync_order_products()public staticWC 3.5.0

Create or update an entry in the wc_admin_order_product_lookup table for an order.

Метод класса: DataStore{}

Хуки из метода

Возвращает

int|true|false. Returns -1 if order won't be processed, or a boolean indicating processing success.

Использование

$result = DataStore::sync_order_products( $order_id );
$order_id(int) (обязательный)
Order ID.

Список изменений

С версии 3.5.0 Введена.

Код DataStore::sync_order_products() WC 8.7.0

public static function sync_order_products( $order_id ) {
	global $wpdb;

	$order = wc_get_order( $order_id );
	if ( ! $order ) {
		return -1;
	}

	$table_name     = self::get_db_table_name();
	$existing_items = $wpdb->get_col(
		$wpdb->prepare(
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			"SELECT order_item_id FROM {$table_name} WHERE order_id = %d",
			$order_id
		)
	);
	$existing_items = array_flip( $existing_items );
	$order_items    = $order->get_items();
	$num_updated    = 0;
	$decimals       = wc_get_price_decimals();
	$round_tax      = 'no' === get_option( 'woocommerce_tax_round_at_subtotal' );

	foreach ( $order_items as $order_item ) {
		$order_item_id = $order_item->get_id();
		unset( $existing_items[ $order_item_id ] );
		$product_qty         = $order_item->get_quantity( 'edit' );
		$shipping_amount     = $order->get_item_shipping_amount( $order_item );
		$shipping_tax_amount = $order->get_item_shipping_tax_amount( $order_item );
		$coupon_amount       = $order->get_item_coupon_amount( $order_item );

		// Skip line items without changes to product quantity.
		if ( ! $product_qty ) {
			$num_updated++;
			continue;
		}

		// Tax amount.
		$tax_amount  = 0;
		$order_taxes = $order->get_taxes();
		$tax_data    = $order_item->get_taxes();
		foreach ( $order_taxes as $tax_item ) {
			$tax_item_id = $tax_item->get_rate_id();
			$tax_amount += isset( $tax_data['total'][ $tax_item_id ] ) ? (float) $tax_data['total'][ $tax_item_id ] : 0;
		}

		$net_revenue = round( $order_item->get_total( 'edit' ), $decimals );
		if ( $round_tax ) {
			$tax_amount = round( $tax_amount, $decimals );
		}

		$result = $wpdb->replace(
			self::get_db_table_name(),
			array(
				'order_item_id'         => $order_item_id,
				'order_id'              => $order->get_id(),
				'product_id'            => wc_get_order_item_meta( $order_item_id, '_product_id' ),
				'variation_id'          => wc_get_order_item_meta( $order_item_id, '_variation_id' ),
				'customer_id'           => $order->get_report_customer_id(),
				'product_qty'           => $product_qty,
				'product_net_revenue'   => $net_revenue,
				'date_created'          => $order->get_date_created( 'edit' )->date( TimeInterval::$sql_datetime_format ),
				'coupon_amount'         => $coupon_amount,
				'tax_amount'            => $tax_amount,
				'shipping_amount'       => $shipping_amount,
				'shipping_tax_amount'   => $shipping_tax_amount,
				// @todo Can this be incorrect if modified by filters?
				'product_gross_revenue' => $net_revenue + $tax_amount + $shipping_amount + $shipping_tax_amount,
			),
			array(
				'%d', // order_item_id.
				'%d', // order_id.
				'%d', // product_id.
				'%d', // variation_id.
				'%d', // customer_id.
				'%d', // product_qty.
				'%f', // product_net_revenue.
				'%s', // date_created.
				'%f', // coupon_amount.
				'%f', // tax_amount.
				'%f', // shipping_amount.
				'%f', // shipping_tax_amount.
				'%f', // product_gross_revenue.
			)
		); // WPCS: cache ok, DB call ok, unprepared SQL ok.

		/**
		 * Fires when product's reports are updated.
		 *
		 * @param int $order_item_id Order Item ID.
		 * @param int $order_id      Order ID.
		 */
		do_action( 'woocommerce_analytics_update_product', $order_item_id, $order->get_id() );

		// Sum the rows affected. Using REPLACE can affect 2 rows if the row already exists.
		$num_updated += 2 === intval( $result ) ? 1 : intval( $result );
	}

	if ( ! empty( $existing_items ) ) {
		$existing_items = array_flip( $existing_items );
		$format         = array_fill( 0, count( $existing_items ), '%d' );
		$format         = implode( ',', $format );
		array_unshift( $existing_items, $order_id );
		$wpdb->query(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"DELETE FROM {$table_name} WHERE order_id = %d AND order_item_id in ({$format})",
				$existing_items
			)
		);
	}

	return ( count( $order_items ) === $num_updated );
}