Refactor shipping_preference

Extract its determination to a separate class, also remove useless CartRepository and use single PU to avoid confusion.
This commit is contained in:
Alex P 2022-07-05 14:25:55 +03:00
parent 67cdf9be8e
commit fff2570124
20 changed files with 245 additions and 264 deletions

View file

@ -43,13 +43,13 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerReceivableBreakdownFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\SellerStatusFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookEventFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper;
use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository;
use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
@ -221,10 +221,6 @@ return array(
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
return new PartnerReferralsData( $dcc_applies );
},
'api.repository.cart' => static function ( ContainerInterface $container ): CartRepository {
$factory = $container->get( 'api.factory.purchase-unit' );
return new CartRepository( $factory );
},
'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository {
$merchant_email = $container->get( 'api.merchant_email' );
$merchant_id = $container->get( 'api.merchant_id' );
@ -298,6 +294,9 @@ return array(
$address_factory = $container->get( 'api.factory.address' );
return new ShippingFactory( $address_factory );
},
'api.factory.shipping-preference' => static function ( ContainerInterface $container ): ShippingPreferenceFactory {
return new ShippingPreferenceFactory();
},
'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory {
$item_factory = $container->get( 'api.factory.item' );
return new AmountFactory(

View file

@ -163,57 +163,23 @@ class OrderEndpoint {
* Creates an order.
*
* @param PurchaseUnit[] $items The purchase unit items for the order.
* @param string $shipping_preference One of ApplicationContext::SHIPPING_PREFERENCE_ values.
* @param Payer|null $payer The payer off the order.
* @param PaymentToken|null $payment_token The payment token.
* @param PaymentMethod|null $payment_method The payment method.
* @param string $paypal_request_id The paypal request id.
* @param bool $shipping_address_is_fixed Whether the shipping address is changeable or not.
*
* @return Order
* @throws RuntimeException If the request fails.
*/
public function create(
array $items,
string $shipping_preference,
Payer $payer = null,
PaymentToken $payment_token = null,
PaymentMethod $payment_method = null,
string $paypal_request_id = '',
bool $shipping_address_is_fixed = false
string $paypal_request_id = ''
): Order {
$contains_physical_goods = false;
$items = array_filter(
$items,
static function ( $item ) use ( &$contains_physical_goods ): bool {
$is_purchase_unit = is_a( $item, PurchaseUnit::class );
/**
* A purchase unit.
*
* @var PurchaseUnit $item
*/
if ( $is_purchase_unit && $item->contains_physical_goods() ) {
$contains_physical_goods = true;
}
return $is_purchase_unit;
}
);
$shipping_preference = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
if ( $contains_physical_goods ) {
if ( $shipping_address_is_fixed ) {
// Checkout + no address given? Probably something weird happened, like no form validation?
// Also note that $items currently always seems to be an array with one item.
if ( $this->has_items_without_shipping( $items ) ) {
$shipping_preference = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
} else {
$shipping_preference = ApplicationContext::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS;
}
} else {
$shipping_preference = ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE;
}
}
$bearer = $this->bearer->bearer();
$data = array(
'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() ) ? 'AUTHORIZE' : $this->intent,
@ -598,20 +564,4 @@ class OrderEndpoint {
$new_order = $this->order( $order_to_update->id() );
return $new_order;
}
/**
* Checks if there is at least one item without shipping.
*
* @param PurchaseUnit[] $items The items.
* @return bool Whether items contains shipping or not.
*/
private function has_items_without_shipping( array $items ): bool {
foreach ( $items as $item ) {
if ( ! $item->shipping() ) {
return true;
}
}
return false;
}
}

View file

@ -152,11 +152,15 @@ class PurchaseUnitFactory {
/**
* Creates a PurchaseUnit based off a WooCommerce cart.
*
* @param \WC_Cart $cart The cart.
* @param \WC_Cart|null $cart The cart.
*
* @return PurchaseUnit
*/
public function from_wc_cart( \WC_Cart $cart ): PurchaseUnit {
public function from_wc_cart( ?\WC_Cart $cart = null ): PurchaseUnit {
if ( ! $cart ) {
$cart = WC()->cart ?? new \WC_Cart();
}
$amount = $this->amount_factory->from_wc_cart( $cart );
$items = array_filter(
$this->item_factory->from_wc_cart( $cart ),

View file

@ -0,0 +1,54 @@
<?php
/**
* Returns shipping_preference for the given state.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use WC_Cart;
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
/**
* Class ShippingPreferenceFactory
*/
class ShippingPreferenceFactory {
/**
* Returns shipping_preference for the given state.
*
* @param PurchaseUnit $purchase_unit Thw PurchaseUnit.
* @param string $context The operation context like 'checkout', 'cart'.
* @param WC_Cart|null $cart The current cart if relevant.
* @return string
*/
public function from_state(
PurchaseUnit $purchase_unit,
string $context,
?WC_Cart $cart = null
): string {
$contains_physical_goods = $purchase_unit->contains_physical_goods();
if ( ! $contains_physical_goods ) {
return ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
}
$has_shipping = null !== $purchase_unit->shipping();
$needs_shipping = $cart && $cart->needs_shipping();
$shipping_address_is_fixed = $needs_shipping && 'checkout' === $context;
if ( $shipping_address_is_fixed ) {
// Checkout + no address given? Probably something weird happened, like no form validation?
if ( ! $has_shipping ) {
return ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
}
return ApplicationContext::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS;
}
return ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE;
}
}

View file

@ -1,45 +0,0 @@
<?php
/**
* The cart repository returns the purchase units from the current \WC_Cart.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Repository
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
/**
* Class CartRepository
*/
class CartRepository implements PurchaseUnitRepositoryInterface {
/**
* The purchase unit factory.
*
* @var PurchaseUnitFactory
*/
private $factory;
/**
* CartRepository constructor.
*
* @param PurchaseUnitFactory $factory The purchase unit factory.
*/
public function __construct( PurchaseUnitFactory $factory ) {
$this->factory = $factory;
}
/**
* Returns all Pur of the WooCommerce cart.
*
* @return PurchaseUnit[]
*/
public function all(): array {
$cart = WC()->cart ?? new \WC_Cart();
return array( $this->factory->from_wc_cart( $cart ) );
}
}

View file

@ -1,26 +0,0 @@
<?php
/**
* The Purchase Unit Repository interface.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Repository
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
/**
* Interface PurchaseUnitRepositoryInterface
*/
interface PurchaseUnitRepositoryInterface {
/**
* Returns all purchase units.
*
* @return PurchaseUnit[]
*/
public function all(): array;
}

View file

@ -108,14 +108,13 @@ return array(
$cart = WC()->cart;
$shipping = WC()->shipping();
$request_data = $container->get( 'button.request-data' );
$repository = $container->get( 'api.repository.cart' );
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
$data_store = \WC_Data_Store::load( 'product' );
$logger = $container->get( 'woocommerce.logger.woocommerce' );
return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store, $logger );
return new ChangeCartEndpoint( $cart, $shipping, $request_data, $purchase_unit_factory, $data_store, $logger );
},
'button.endpoint.create-order' => static function ( ContainerInterface $container ): CreateOrderEndpoint {
$request_data = $container->get( 'button.request-data' );
$cart_repository = $container->get( 'api.repository.cart' );
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
$order_endpoint = $container->get( 'api.endpoint.order' );
$payer_factory = $container->get( 'api.factory.payer' );
@ -126,8 +125,8 @@ return array(
$logger = $container->get( 'woocommerce.logger.woocommerce' );
return new CreateOrderEndpoint(
$request_data,
$cart_repository,
$purchase_unit_factory,
$container->get( 'api.factory.shipping-preference' ),
$order_endpoint,
$payer_factory,
$session_handler,

View file

@ -13,7 +13,7 @@ use Exception;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
/**
@ -46,11 +46,11 @@ class ChangeCartEndpoint implements EndpointInterface {
private $request_data;
/**
* Contains purchase units based off the current WC cart.
* The PurchaseUnit factory.
*
* @var CartRepository
* @var PurchaseUnitFactory
*/
private $repository;
private $purchase_unit_factory;
/**
* The product data store.
@ -69,28 +69,28 @@ class ChangeCartEndpoint implements EndpointInterface {
/**
* ChangeCartEndpoint constructor.
*
* @param \WC_Cart $cart The current WC cart object.
* @param \WC_Shipping $shipping The current WC shipping object.
* @param RequestData $request_data The request data helper.
* @param CartRepository $repository The repository for the current purchase items.
* @param \WC_Data_Store $product_data_store The data store for products.
* @param LoggerInterface $logger The logger.
* @param \WC_Cart $cart The current WC cart object.
* @param \WC_Shipping $shipping The current WC shipping object.
* @param RequestData $request_data The request data helper.
* @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory.
* @param \WC_Data_Store $product_data_store The data store for products.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
\WC_Cart $cart,
\WC_Shipping $shipping,
RequestData $request_data,
CartRepository $repository,
PurchaseUnitFactory $purchase_unit_factory,
\WC_Data_Store $product_data_store,
LoggerInterface $logger
) {
$this->cart = $cart;
$this->shipping = $shipping;
$this->request_data = $request_data;
$this->repository = $repository;
$this->product_data_store = $product_data_store;
$this->logger = $logger;
$this->cart = $cart;
$this->shipping = $shipping;
$this->request_data = $request_data;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->product_data_store = $product_data_store;
$this->logger = $logger;
}
/**
@ -292,11 +292,7 @@ class ChangeCartEndpoint implements EndpointInterface {
* @return array
*/
private function generate_purchase_units(): array {
return array_map(
static function ( PurchaseUnit $line_item ): array {
return $line_item->to_array();
},
$this->repository->all()
);
$pu = $this->purchase_unit_factory->from_wc_cart();
return array( $pu->to_array() );
}
}

View file

@ -23,7 +23,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
@ -48,13 +48,6 @@ class CreateOrderEndpoint implements EndpointInterface {
*/
private $request_data;
/**
* The cart repository.
*
* @var CartRepository
*/
private $cart_repository;
/**
* The PurchaseUnit factory.
*
@ -62,6 +55,13 @@ class CreateOrderEndpoint implements EndpointInterface {
*/
private $purchase_unit_factory;
/**
* The shipping_preference factory.
*
* @var ShippingPreferenceFactory
*/
private $shipping_preference_factory;
/**
* The order endpoint.
*
@ -105,11 +105,11 @@ class CreateOrderEndpoint implements EndpointInterface {
private $parsed_request_data;
/**
* The array of purchase units for order.
* The purchase unit for order.
*
* @var PurchaseUnit[]
* @var PurchaseUnit|null
*/
private $purchase_units;
private $purchase_unit;
/**
* Whether a new user must be registered during checkout.
@ -128,21 +128,21 @@ class CreateOrderEndpoint implements EndpointInterface {
/**
* CreateOrderEndpoint constructor.
*
* @param RequestData $request_data The RequestData object.
* @param CartRepository $cart_repository The CartRepository object.
* @param PurchaseUnitFactory $purchase_unit_factory The Purchaseunit factory.
* @param OrderEndpoint $order_endpoint The OrderEndpoint object.
* @param PayerFactory $payer_factory The PayerFactory object.
* @param SessionHandler $session_handler The SessionHandler object.
* @param Settings $settings The Settings object.
* @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
* @param bool $registration_needed Whether a new user must be registered during checkout.
* @param LoggerInterface $logger The logger.
* @param RequestData $request_data The RequestData object.
* @param PurchaseUnitFactory $purchase_unit_factory The PurchaseUnit factory.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param OrderEndpoint $order_endpoint The OrderEndpoint object.
* @param PayerFactory $payer_factory The PayerFactory object.
* @param SessionHandler $session_handler The SessionHandler object.
* @param Settings $settings The Settings object.
* @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
* @param bool $registration_needed Whether a new user must be registered during checkout.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
RequestData $request_data,
CartRepository $cart_repository,
PurchaseUnitFactory $purchase_unit_factory,
ShippingPreferenceFactory $shipping_preference_factory,
OrderEndpoint $order_endpoint,
PayerFactory $payer_factory,
SessionHandler $session_handler,
@ -152,16 +152,16 @@ class CreateOrderEndpoint implements EndpointInterface {
LoggerInterface $logger
) {
$this->request_data = $request_data;
$this->cart_repository = $cart_repository;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->api_endpoint = $order_endpoint;
$this->payer_factory = $payer_factory;
$this->session_handler = $session_handler;
$this->settings = $settings;
$this->early_order_handler = $early_order_handler;
$this->registration_needed = $registration_needed;
$this->logger = $logger;
$this->request_data = $request_data;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->api_endpoint = $order_endpoint;
$this->payer_factory = $payer_factory;
$this->session_handler = $session_handler;
$this->settings = $settings;
$this->early_order_handler = $early_order_handler;
$this->registration_needed = $registration_needed;
$this->logger = $logger;
}
/**
@ -198,9 +198,9 @@ class CreateOrderEndpoint implements EndpointInterface {
)
);
}
$this->purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) );
$this->purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
} else {
$this->purchase_units = $this->cart_repository->all();
$this->purchase_unit = $this->purchase_unit_factory->from_wc_cart();
// The cart does not have any info about payment method, so we must handle free trial here.
if ( (
@ -209,10 +209,10 @@ class CreateOrderEndpoint implements EndpointInterface {
)
&& $this->is_free_trial_cart()
) {
$this->purchase_units[0]->set_amount(
$this->purchase_unit->set_amount(
new Amount(
new Money( 1.0, $this->purchase_units[0]->amount()->currency_code() ),
$this->purchase_units[0]->amount()->breakdown()
new Money( 1.0, $this->purchase_unit->amount()->currency_code() ),
$this->purchase_unit->amount()->breakdown()
)
);
}
@ -329,17 +329,21 @@ class CreateOrderEndpoint implements EndpointInterface {
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
private function create_paypal_order( \WC_Order $wc_order = null ): Order {
$needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
$shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
assert( $this->purchase_unit instanceof PurchaseUnit );
$shipping_preference = $this->shipping_preference_factory->from_state(
$this->purchase_unit,
$this->parsed_request_data['context'],
WC()->cart
);
try {
return $this->api_endpoint->create(
$this->purchase_units,
array( $this->purchase_unit ),
$shipping_preference,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
$this->payment_method()
);
} catch ( PayPalApiException $exception ) {
// Looks like currently there is no proper way to validate the shipping address for PayPal,
@ -354,17 +358,14 @@ class CreateOrderEndpoint implements EndpointInterface {
) ) {
$this->logger->info( 'Invalid shipping address for order creation, retrying without it.' );
foreach ( $this->purchase_units as $purchase_unit ) {
$purchase_unit->set_shipping( null );
}
$this->purchase_unit->set_shipping( null );
return $this->api_endpoint->create(
$this->purchase_units,
array( $this->purchase_unit ),
$shipping_preference,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
$this->payment_method()
);
}

View file

@ -29,6 +29,7 @@ return array(
$repository,
$endpoint,
$purchase_unit_factory,
$container->get( 'api.factory.shipping-preference' ),
$payer_factory,
$environment
);

View file

@ -13,6 +13,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use Psr\Log\LoggerInterface;
@ -58,6 +59,13 @@ class RenewalHandler {
*/
private $purchase_unit_factory;
/**
* The shipping_preference factory.
*
* @var ShippingPreferenceFactory
*/
private $shipping_preference_factory;
/**
* The payer factory.
*
@ -75,28 +83,31 @@ class RenewalHandler {
/**
* RenewalHandler constructor.
*
* @param LoggerInterface $logger The logger.
* @param PaymentTokenRepository $repository The payment token repository.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param PayerFactory $payer_factory The payer factory.
* @param Environment $environment The environment.
* @param LoggerInterface $logger The logger.
* @param PaymentTokenRepository $repository The payment token repository.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param PayerFactory $payer_factory The payer factory.
* @param Environment $environment The environment.
*/
public function __construct(
LoggerInterface $logger,
PaymentTokenRepository $repository,
OrderEndpoint $order_endpoint,
PurchaseUnitFactory $purchase_unit_factory,
ShippingPreferenceFactory $shipping_preference_factory,
PayerFactory $payer_factory,
Environment $environment
) {
$this->logger = $logger;
$this->repository = $repository;
$this->order_endpoint = $order_endpoint;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->payer_factory = $payer_factory;
$this->environment = $environment;
$this->logger = $logger;
$this->repository = $repository;
$this->order_endpoint = $order_endpoint;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->payer_factory = $payer_factory;
$this->environment = $environment;
}
/**
@ -141,11 +152,16 @@ class RenewalHandler {
if ( ! $token ) {
return;
}
$purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
$payer = $this->payer_factory->from_customer( $customer );
$purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
$payer = $this->payer_factory->from_customer( $customer );
$shipping_preference = $this->shipping_preference_factory->from_state(
$purchase_unit,
'renewal'
);
$order = $this->order_endpoint->create(
array( $purchase_unit ),
$shipping_preference,
$payer,
$token
);

View file

@ -87,6 +87,7 @@ return array(
$page_id,
$environment,
$payment_token_repository,
$container->get( 'api.factory.shipping-preference' ),
$logger,
$payments_endpoint,
$order_endpoint,
@ -123,6 +124,7 @@ return array(
$transaction_url_provider,
$payment_token_repository,
$purchase_unit_factory,
$container->get( 'api.factory.shipping-preference' ),
$payer_factory,
$order_endpoint,
$subscription_helper,

View file

@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
@ -111,6 +112,13 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
*/
private $purchase_unit_factory;
/**
* The shipping_preference factory.
*
* @var ShippingPreferenceFactory
*/
private $shipping_preference_factory;
/**
* The payer factory.
*
@ -167,6 +175,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
* @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base.
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param PayerFactory $payer_factory The payer factory.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param SubscriptionHelper $subscription_helper The subscription helper.
@ -186,6 +195,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
TransactionUrlProvider $transaction_url_provider,
PaymentTokenRepository $payment_token_repository,
PurchaseUnitFactory $purchase_unit_factory,
ShippingPreferenceFactory $shipping_preference_factory,
PayerFactory $payer_factory,
OrderEndpoint $order_endpoint,
SubscriptionHelper $subscription_helper,
@ -252,16 +262,17 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
)
);
$this->module_url = $module_url;
$this->payment_token_repository = $payment_token_repository;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->payer_factory = $payer_factory;
$this->order_endpoint = $order_endpoint;
$this->transaction_url_provider = $transaction_url_provider;
$this->subscription_helper = $subscription_helper;
$this->logger = $logger;
$this->payments_endpoint = $payments_endpoint;
$this->state = $state;
$this->module_url = $module_url;
$this->payment_token_repository = $payment_token_repository;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->payer_factory = $payer_factory;
$this->order_endpoint = $order_endpoint;
$this->transaction_url_provider = $transaction_url_provider;
$this->subscription_helper = $subscription_helper;
$this->logger = $logger;
$this->payments_endpoint = $payments_endpoint;
$this->state = $state;
}
/**

View file

@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
@ -118,6 +119,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
*/
protected $payment_token_repository;
/**
* The shipping_preference factory.
*
* @var ShippingPreferenceFactory
*/
private $shipping_preference_factory;
/**
* The payments endpoint
*
@ -183,6 +191,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
* @param Environment $environment The environment.
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param LoggerInterface $logger The logger.
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
* @param OrderEndpoint $order_endpoint The order endpoint.
@ -202,6 +211,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
string $page_id,
Environment $environment,
PaymentTokenRepository $payment_token_repository,
ShippingPreferenceFactory $shipping_preference_factory,
LoggerInterface $logger,
PaymentsEndpoint $payments_endpoint,
OrderEndpoint $order_endpoint,
@ -223,6 +233,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
$this->id = self::ID;
$this->order_processor = $order_processor;
$this->authorized_payments = $authorized_payments_processor;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->settings_renderer = $settings_renderer;
$this->config = $config;
$this->session_handler = $session_handler;

View file

@ -82,9 +82,16 @@ trait ProcessPaymentTrait {
$purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order );
$payer = $this->payer_factory->from_customer( $customer );
$shipping_preference = $this->shipping_preference_factory->from_state(
$purchase_unit,
''
);
try {
$order = $this->order_endpoint->create(
array( $purchase_unit ),
$shipping_preference,
$payer,
$selected_token
);

View file

@ -952,7 +952,7 @@ class OrderEndpointTest extends TestCase
->expects('email_address')
->andReturn('');
$result = $testee->create([$purchaseUnit], $payer);
$result = $testee->create([$purchaseUnit], ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING, $payer);
$this->assertEquals($expectedOrder, $result);
}
@ -1049,7 +1049,7 @@ class OrderEndpointTest extends TestCase
$payerName = Mockery::mock(PayerName::class);
$payer->expects('name')->andReturn($payerName);
$payer->expects('to_array')->andReturn(['payer']);
$result = $testee->create([$purchaseUnit], $payer);
$result = $testee->create([$purchaseUnit], ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE, $payer);
$this->assertEquals($expectedOrder, $result);
}
@ -1141,7 +1141,7 @@ class OrderEndpointTest extends TestCase
$payerName = Mockery::mock(PayerName::class);
$payer->expects('name')->andReturn($payerName);
$payer->expects('to_array')->andReturn(['payer']);
$testee->create([$purchaseUnit], $payer);
$testee->create([$purchaseUnit], ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING, $payer);
}
public function testCreateForPurchaseUnitsIsNot201()
@ -1232,6 +1232,6 @@ class OrderEndpointTest extends TestCase
$payerName = Mockery::mock(PayerName::class);
$payer->expects('name')->andReturn($payerName);
$payer->expects('to_array')->andReturn(['payer']);
$testee->create([$purchaseUnit], $payer);
$testee->create([$purchaseUnit], ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE, $payer);
}
}

View file

@ -5,7 +5,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\TestCase;
use Mockery;
use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
@ -17,7 +17,7 @@ class ChangeCartEndpointTest extends TestCase
/**
* @dataProvider dataForTestProducts
*/
public function testProducts($data, $products, $lineItems, $responseExpectation) {
public function testProducts($data, $products, $responseExpectation) {
$dataStore = Mockery::mock(\WC_Data_Store::class);
$cart = Mockery::mock(\WC_Cart::class);
@ -59,16 +59,21 @@ class ChangeCartEndpointTest extends TestCase
->expects('read_request')
->with(ChangeCartEndpoint::nonce())
->andReturn($data);
$cartRepository = Mockery::mock(CartRepository::class);
$cartRepository
->expects('all')
->andReturn($lineItems);
$pu = Mockery::mock(PurchaseUnit::class);
$pu
->shouldReceive('to_array')
->andReturn($responseExpectation[0]);
$purchase_unit_factory = Mockery::mock(PurchaseUnitFactory::class);
$purchase_unit_factory
->expects('from_wc_cart')
->andReturn($pu);
$testee = new ChangeCartEndpoint(
$cart,
$shipping,
$requestData,
$cartRepository,
$purchase_unit_factory,
$dataStore,
new NullLogger()
);
@ -97,15 +102,6 @@ class ChangeCartEndpointTest extends TestCase
->with('variable')
->andReturn(true);
$defaultLineItem = Mockery::mock(PurchaseUnit::class);
$defaultLineItem
->shouldReceive('to_array')
->andReturn([1]);
$variationLineItem = Mockery::mock(PurchaseUnit::class);
$variationLineItem
->shouldReceive('to_array')
->andReturn([2]);
$testData = [
'default' => [
[
@ -120,9 +116,6 @@ class ChangeCartEndpointTest extends TestCase
[
$defaultProduct,
],
[
$defaultLineItem,
],
[
[1],
]
@ -162,11 +155,7 @@ class ChangeCartEndpointTest extends TestCase
$variationProduct,
],
[
$defaultLineItem,
$variationLineItem,
],
[
[1],[2]
[1, 2]
]
]
];

View file

@ -10,7 +10,7 @@ use ReflectionClass;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\TestCase;
@ -145,7 +145,7 @@ class CreateOrderEndpointTest extends TestCase
protected function mockTestee()
{
$request_data = Mockery::mock(RequestData::class);
$cart_repository = Mockery::mock(CartRepository::class);
$shippingPreferenceFactory = Mockery::mock(ShippingPreferenceFactory::class);
$purchase_unit_factory = Mockery::mock(PurchaseUnitFactory::class);
$order_endpoint = Mockery::mock(OrderEndpoint::class);
$payer_factory = Mockery::mock(PayerFactory::class);
@ -155,8 +155,8 @@ class CreateOrderEndpointTest extends TestCase
$testee = new CreateOrderEndpoint(
$request_data,
$cart_repository,
$purchase_unit_factory,
$shippingPreferenceFactory,
$order_endpoint,
$payer_factory,
$session_handler,

View file

@ -16,6 +16,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\TestCase;
use Mockery;
@ -31,6 +32,7 @@ class RenewalHandlerTest extends TestCase
private $repository;
private $orderEndpoint;
private $purchaseUnitFactory;
private $shippingPreferenceFactory;
private $payerFactory;
private $environment;
private $sut;
@ -43,6 +45,7 @@ class RenewalHandlerTest extends TestCase
$this->repository = Mockery::mock(PaymentTokenRepository::class);
$this->orderEndpoint = Mockery::mock(OrderEndpoint::class);
$this->purchaseUnitFactory = Mockery::mock(PurchaseUnitFactory::class);
$this->shippingPreferenceFactory = Mockery::mock(ShippingPreferenceFactory::class);
$this->payerFactory = Mockery::mock(PayerFactory::class);
$this->environment = new Environment(new Dictionary([]));
@ -56,6 +59,7 @@ class RenewalHandlerTest extends TestCase
$this->repository,
$this->orderEndpoint,
$this->purchaseUnitFactory,
$this->shippingPreferenceFactory,
$this->payerFactory,
$this->environment
);
@ -133,8 +137,12 @@ class RenewalHandlerTest extends TestCase
$this->payerFactory->shouldReceive('from_customer')
->andReturn($payer);
$this->shippingPreferenceFactory->shouldReceive('from_state')
->with($purchaseUnit, 'renewal')
->andReturn('no_shipping');
$this->orderEndpoint->shouldReceive('create')
->with([$purchaseUnit], $payer, $token)
->with([$purchaseUnit], 'no_shipping', $payer, $token)
->andReturn($order);
$wcOrder->shouldReceive('update_status');

View file

@ -10,6 +10,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use Psr\Log\NullLogger;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Session\SessionHandler;
@ -44,6 +45,7 @@ class WcGatewayTest extends TestCase
private $subscriptionHelper;
private $environment;
private $paymentTokenRepository;
private $shipping_preference_factory;
private $logger;
private $paymentsEndpoint;
private $orderEndpoint;
@ -67,6 +69,7 @@ class WcGatewayTest extends TestCase
$this->subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
$this->environment = Mockery::mock(Environment::class);
$this->paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$this->shipping_preference_factory = Mockery::mock(ShippingPreferenceFactory::class);
$this->logger = Mockery::mock(LoggerInterface::class);
$this->paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$this->orderEndpoint = Mockery::mock(OrderEndpoint::class);
@ -102,6 +105,7 @@ class WcGatewayTest extends TestCase
PayPalGateway::ID,
$this->environment,
$this->paymentTokenRepository,
$this->shipping_preference_factory,
$this->logger,
$this->paymentsEndpoint,
$this->orderEndpoint,