Move Draft Order Handling to Shared Trait (DraftOrderTrait) (https://github.com/woocommerce/woocommerce-blocks/pull/5323)
* Introduce shared trait for draft order handling (DraftOrderTrait) * Use trait where needed for maybe_release_stock * Introduce woocommerce_blocks_cart_update_customer_from_request This hook gets the request data and customer object, and from there, 3rd parties could grab a draft order and manually update it if needed (if the use cases requires this). * Revert "Introduce woocommerce_blocks_cart_update_customer_from_request" This reverts commit 6620818eb1e03b87c6eca0d757ec8b78802e3c57.
This commit is contained in:
parent
29fa0a61e6
commit
b0f9e524a3
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Routes;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\AbstractSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
|
||||
|
||||
/**
|
||||
* Abstract Cart Route
|
||||
|
@ -112,21 +112,6 @@ abstract class AbstractCartRoute extends AbstractRoute {
|
|||
wc()->cart->calculate_totals();
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a draft order, releases stock.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function maybe_release_stock() {
|
||||
$draft_order = wc()->session->get( 'store_api_draft_order', 0 );
|
||||
|
||||
if ( ! $draft_order ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wc_release_stock_for_order( $draft_order );
|
||||
}
|
||||
|
||||
/**
|
||||
* For non-GET endpoints, require and validate a nonce to prevent CSRF attacks.
|
||||
*
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Routes;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* CartRemoveItem class.
|
||||
*
|
||||
* @internal This API is used internally by Blocks--it is still in flux and may be subject to revisions.
|
||||
*/
|
||||
class CartRemoveItem extends AbstractCartRoute {
|
||||
use DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* Get the path of this REST route.
|
||||
*
|
||||
|
@ -59,4 +63,19 @@ class CartRemoveItem extends AbstractCartRoute {
|
|||
|
||||
return rest_ensure_response( $this->schema->get_item_response( $cart ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a draft order, releases stock.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function maybe_release_stock() {
|
||||
$draft_order_id = $this->get_draft_order_id();
|
||||
|
||||
if ( ! $draft_order_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wc_release_stock_for_order( $draft_order_id );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Routes;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\BillingAddressSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\ShippingAddressSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* CartUpdateCustomer class.
|
||||
|
@ -13,6 +11,8 @@ use Automattic\WooCommerce\Blocks\StoreApi\Schemas\ShippingAddressSchema;
|
|||
* @internal This API is used internally by Blocks--it is still in flux and may be subject to revisions.
|
||||
*/
|
||||
class CartUpdateCustomer extends AbstractCartRoute {
|
||||
use DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* Get the namespace for this route.
|
||||
*
|
||||
|
@ -128,13 +128,13 @@ class CartUpdateCustomer extends AbstractCartRoute {
|
|||
}
|
||||
|
||||
/**
|
||||
* If there is a draft order, update customer data there also.
|
||||
* If there is a draft order, update the customer data within that also so the
|
||||
* cart and order are kept in sync.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function maybe_update_order() {
|
||||
$draft_order_id = wc()->session->get( 'store_api_draft_order', 0 );
|
||||
$draft_order = $draft_order_id ? wc_get_order( $draft_order_id ) : false;
|
||||
$draft_order = $this->get_draft_order();
|
||||
|
||||
if ( ! $draft_order ) {
|
||||
return;
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Routes;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\InvalidStockLevelsInCartException;
|
||||
use Automattic\WooCommerce\Blocks\Package;
|
||||
use Automattic\WooCommerce\Blocks\Domain\Services\CreateAccount;
|
||||
use Automattic\WooCommerce\Blocks\Package;
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentContext;
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentResult;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\AbstractSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\DraftOrderTrait;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\InvalidStockLevelsInCartException;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\OrderController;
|
||||
use Automattic\WooCommerce\Checkout\Helpers\ReserveStock;
|
||||
use Automattic\WooCommerce\Checkout\Helpers\ReserveStockException;
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentResult;
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentContext;
|
||||
|
||||
/**
|
||||
* Checkout class.
|
||||
|
@ -19,6 +20,8 @@ use Automattic\WooCommerce\Blocks\Payments\PaymentContext;
|
|||
* @internal This API is used internally by Blocks--it is still in flux and may be subject to revisions.
|
||||
*/
|
||||
class Checkout extends AbstractCartRoute {
|
||||
use DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* Holds the current order being processed.
|
||||
*
|
||||
|
@ -349,58 +352,15 @@ class Checkout extends AbstractCartRoute {
|
|||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets draft order data from the customer session.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_draft_order_id() {
|
||||
return wc()->session->get( 'store_api_draft_order', 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates draft order data in the customer session.
|
||||
*
|
||||
* @param integer $order_id Draft order ID.
|
||||
*/
|
||||
private function set_draft_order_id( $order_id ) {
|
||||
wc()->session->set( 'store_api_draft_order', $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the passed argument is a draft order or an order that is
|
||||
* pending/failed and the cart hasn't changed.
|
||||
*
|
||||
* @param \WC_Order $order_object Order object to check.
|
||||
* @return boolean Whether the order is valid as a draft order.
|
||||
*/
|
||||
private function is_valid_draft_order( $order_object ) {
|
||||
if ( ! $order_object instanceof \WC_Order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Draft orders are okay.
|
||||
if ( $order_object->has_status( 'checkout-draft' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pending and failed orders can be retried if the cart hasn't changed.
|
||||
if ( $order_object->needs_payment() && $order_object->has_cart_hash( wc()->cart->get_cart_hash() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update a draft order based on the cart.
|
||||
*
|
||||
* @throws RouteException On error.
|
||||
*/
|
||||
private function create_or_update_draft_order() {
|
||||
$this->order = $this->get_draft_order_id() ? wc_get_order( $this->get_draft_order_id() ) : null;
|
||||
$this->order = $this->get_draft_order();
|
||||
|
||||
if ( ! $this->is_valid_draft_order( $this->order ) ) {
|
||||
if ( ! $this->order ) {
|
||||
$this->order = $this->order_controller->create_order_from_cart();
|
||||
} else {
|
||||
$this->order_controller->update_order_from_cart( $this->order );
|
||||
|
@ -466,7 +426,6 @@ class Checkout extends AbstractCartRoute {
|
|||
$reserve_stock = new ReserveStock();
|
||||
$reserve_stock->reserve_stock_for_order( $this->order, 10 );
|
||||
} catch ( ReserveStockException $e ) {
|
||||
$error_data = $e->getErrorData();
|
||||
throw new RouteException(
|
||||
$e->getErrorCode(),
|
||||
$e->getMessage(),
|
||||
|
|
|
@ -40,14 +40,14 @@ class RoutesController {
|
|||
/**
|
||||
* Get a route class instance.
|
||||
*
|
||||
* @throws Exception If the schema does not exist.
|
||||
* @throws \Exception If the schema does not exist.
|
||||
*
|
||||
* @param string $name Name of schema.
|
||||
* @return AbstractRoute
|
||||
*/
|
||||
public function get( $name ) {
|
||||
if ( ! isset( $this->routes[ $name ] ) ) {
|
||||
throw new Exception( $name . ' route does not exist' );
|
||||
throw new \Exception( $name . ' route does not exist' );
|
||||
}
|
||||
return $this->routes[ $name ];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Schemas;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\DraftOrderTrait;
|
||||
use Automattic\WooCommerce\Checkout\Helpers\ReserveStock;
|
||||
|
||||
/**
|
||||
* CartItemSchema class.
|
||||
*
|
||||
|
@ -10,6 +10,8 @@ use Automattic\WooCommerce\Checkout\Helpers\ReserveStock;
|
|||
* @since 2.5.0
|
||||
*/
|
||||
class CartItemSchema extends ProductSchema {
|
||||
use DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* The schema item name.
|
||||
*
|
||||
|
@ -374,9 +376,8 @@ class CartItemSchema extends ProductSchema {
|
|||
return null;
|
||||
}
|
||||
|
||||
$draft_order = wc()->session->get( 'store_api_draft_order', 0 );
|
||||
$reserve_stock = new ReserveStock();
|
||||
$reserved_stock = $reserve_stock->get_reserved_stock( $product, $draft_order );
|
||||
$reserved_stock = $reserve_stock->get_reserved_stock( $product, $this->get_draft_order_id() );
|
||||
|
||||
return $product->get_stock_quantity() - $reserved_stock;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
namespace Automattic\WooCommerce\Blocks\StoreApi\Utilities;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Routes\RouteException;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\DraftOrderTrait;
|
||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\NoticeHandler;
|
||||
use Automattic\WooCommerce\Blocks\Utils\ArrayUtils;
|
||||
use Automattic\WooCommerce\Checkout\Helpers\ReserveStock;
|
||||
|
@ -15,6 +16,8 @@ use WP_Error;
|
|||
* @since 2.5.0
|
||||
*/
|
||||
class CartController {
|
||||
use DraftOrderTrait;
|
||||
|
||||
/**
|
||||
* Makes the cart and sessions available to a route by loading them from core.
|
||||
*/
|
||||
|
@ -963,8 +966,7 @@ class CartController {
|
|||
*/
|
||||
protected function get_remaining_stock_for_product( $product ) {
|
||||
$reserve_stock = new ReserveStock();
|
||||
$draft_order = wc()->session->get( 'store_api_draft_order', 0 );
|
||||
$qty_reserved = $reserve_stock->get_reserved_stock( $product, $draft_order );
|
||||
$qty_reserved = $reserve_stock->get_reserved_stock( $product, $this->get_draft_order_id() );
|
||||
|
||||
return $product->get_stock_quantity() - $qty_reserved;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\StoreApi\Utilities;
|
||||
|
||||
/**
|
||||
* DraftOrderTrait
|
||||
*
|
||||
* Shared functionality for getting and setting draft order IDs from session.
|
||||
*/
|
||||
trait DraftOrderTrait {
|
||||
/**
|
||||
* Gets draft order data from the customer session.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function get_draft_order_id() {
|
||||
return wc()->session->get( 'store_api_draft_order', 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates draft order data in the customer session.
|
||||
*
|
||||
* @param integer $order_id Draft order ID.
|
||||
*/
|
||||
protected function set_draft_order_id( $order_id ) {
|
||||
wc()->session->set( 'store_api_draft_order', $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the draft order ID to return an order object, if valid.
|
||||
*
|
||||
* @return \WC_Order|null;
|
||||
*/
|
||||
protected function get_draft_order() {
|
||||
$draft_order_id = $this->get_draft_order_id();
|
||||
$draft_order = $draft_order_id ? wc_get_order( $draft_order_id ) : false;
|
||||
|
||||
return $this->is_valid_draft_order( $draft_order ) ? $draft_order : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the passed argument is a draft order or an order that is
|
||||
* pending/failed and the cart hasn't changed.
|
||||
*
|
||||
* @param \WC_Order $order_object Order object to check.
|
||||
* @return boolean Whether the order is valid as a draft order.
|
||||
*/
|
||||
protected function is_valid_draft_order( $order_object ) {
|
||||
if ( ! $order_object instanceof \WC_Order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Draft orders are okay.
|
||||
if ( $order_object->has_status( 'checkout-draft' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pending and failed orders can be retried if the cart hasn't changed.
|
||||
if ( $order_object->needs_payment() && $order_object->has_cart_hash( wc()->cart->get_cart_hash() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue