Skip to content

Commit 160d7b7

Browse files
committed
Merge remote-tracking branch 'origin/2.4-develop' into PWA-1311
2 parents 3aa76e9 + 5734ca9 commit 160d7b7

17 files changed

+551
-195
lines changed

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
<requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity>
3636
<requiredEntity type="custom_attribute_array">CustomAttributeCategoryIds</requiredEntity>
3737
</entity>
38+
<entity name="ApiSimpleProductZeroQty" type="product">
39+
<requiredEntity type="product_extension_attribute">EavStock0</requiredEntity>
40+
</entity>
3841
<entity name="ApiSimpleProductWithNoSpace" type="product" extends="ApiSimpleProduct">
3942
<data key="name">TestFooBar</data>
4043
<data key="sku" unique="suffix">foobar</data>

app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerOrderViewSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1010
<section name="StorefrontCustomerOrderViewSection">
1111
<element name="reorder" type="text" selector="a.action.order" timeout="30"/>
12+
<element name="view" type="text" selector="a.action.view" timeout="30"/>
1213
<element name="orderTitle" type="text" selector=".page-title span"/>
1314
<element name="myOrdersTable" type="text" selector="#my-orders-table"/>
1415
<element name="subtotal" type="text" selector=".subtotal .amount"/>

app/code/Magento/Quote/Model/QuoteManagement.php

Lines changed: 97 additions & 71 deletions
Large diffs are not rendered by default.

app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\Customer\Api\Data\GroupInterface;
1919
use Magento\Customer\Model\Customer;
2020
use Magento\Customer\Model\CustomerFactory;
21+
use Magento\Customer\Model\Session as CustomerSession;
2122
use Magento\Framework\Api\DataObjectHelper;
2223
use Magento\Framework\App\RequestInterface;
2324
use Magento\Framework\Event\ManagerInterface;
@@ -274,7 +275,7 @@ protected function setUp(): void
274275
)
275276
->disableOriginalConstructor()
276277
->getMock();
277-
$this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class);
278+
$this->customerSessionMock = $this->createMock(CustomerSession::class);
278279
$this->accountManagementMock = $this->getMockForAbstractClass(AccountManagementInterface::class);
279280

280281
$this->quoteFactoryMock = $this->createPartialMock(QuoteFactory::class, ['create']);
@@ -737,11 +738,9 @@ public function testSubmit(): void
737738
$convertedShipping = $this->createPartialMockForAbstractClass(OrderAddressInterface::class, ['setData']);
738739
$convertedPayment = $this->getMockForAbstractClass(OrderPaymentInterface::class);
739740
$convertedQuoteItem = $this->getMockForAbstractClass(OrderItemInterface::class);
740-
741741
$addresses = [$convertedShipping, $convertedBilling];
742742
$quoteItems = [$quoteItem];
743743
$convertedItems = [$convertedQuoteItem];
744-
745744
$quote = $this->getQuote(
746745
$isGuest,
747746
$isVirtual,
@@ -976,9 +975,6 @@ public function testPlaceOrder(): void
976975
$this->quoteMock->expects($this->once())
977976
->method('getCheckoutMethod')
978977
->willReturn(Onepage::METHOD_CUSTOMER);
979-
$this->quoteMock->expects($this->never())
980-
->method('setCustomerIsGuest')
981-
->with(true);
982978

983979
$this->remoteAddressMock
984980
->method('getRemoteAddress')

app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForUser.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
1313
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1414
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
15+
use Magento\Quote\Api\CartManagementInterface;
1516
use Magento\Quote\Api\CartRepositoryInterface;
1617
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
1718
use Magento\Quote\Model\Quote;
@@ -32,6 +33,11 @@ class GetCartForUser
3233
*/
3334
private $cartRepository;
3435

36+
/**
37+
* @var CheckCartCheckoutAllowance
38+
*/
39+
private $checkoutAllowance;
40+
3541
/**
3642
* @var StoreRepositoryInterface
3743
*/
@@ -40,15 +46,18 @@ class GetCartForUser
4046
/**
4147
* @param MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId
4248
* @param CartRepositoryInterface $cartRepository
49+
* @param CheckCartCheckoutAllowance $checkoutAllowance
4350
* @param StoreRepositoryInterface $storeRepository
4451
*/
4552
public function __construct(
4653
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
4754
CartRepositoryInterface $cartRepository,
55+
CheckCartCheckoutAllowance $checkoutAllowance,
4856
StoreRepositoryInterface $storeRepository = null
4957
) {
5058
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
5159
$this->cartRepository = $cartRepository;
60+
$this->checkoutAllowance = $checkoutAllowance;
5261
$this->storeRepository = $storeRepository ?: ObjectManager::getInstance()->get(StoreRepositoryInterface::class);
5362
}
5463

@@ -107,6 +116,36 @@ public function execute(string $cartHash, ?int $customerId, int $storeId): Quote
107116
return $cart;
108117
}
109118

119+
/**
120+
* Gets the cart for the user validated and configured for guest checkout if applicable
121+
*
122+
* @param string $cartHash
123+
* @param int|null $customerId
124+
* @param int $storeId
125+
* @return Quote
126+
* @throws GraphQlAuthorizationException
127+
* @throws GraphQlInputException
128+
* @throws GraphQlNoSuchEntityException
129+
*/
130+
public function getCartForCheckout(string $cartHash, ?int $customerId, int $storeId): Quote
131+
{
132+
try {
133+
$cart = $this->execute($cartHash, $customerId, $storeId);
134+
} catch (NoSuchEntityException $e) {
135+
throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e);
136+
}
137+
$this->checkoutAllowance->execute($cart);
138+
139+
if ((null === $customerId || 0 === $customerId)) {
140+
if (!$cart->getCustomerEmail()) {
141+
throw new GraphQlInputException(__("Guest email for cart is missing."));
142+
}
143+
$cart->setCheckoutMethod(CartManagementInterface::METHOD_GUEST);
144+
}
145+
146+
return $cart;
147+
}
148+
110149
/**
111150
* Sets cart currency based on specified store.
112151
*
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Cart\Payment;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Quote\Api\Data\PaymentInterface;
12+
use Magento\Quote\Api\Data\PaymentInterfaceFactory;
13+
14+
/**
15+
* Build payment method objects
16+
*/
17+
class PaymentMethodBuilder
18+
{
19+
/**
20+
* @var PaymentInterfaceFactory
21+
*/
22+
private $paymentFactory;
23+
24+
/**
25+
* @var AdditionalDataProviderPool
26+
*/
27+
private $paymentDataProvider;
28+
29+
/**
30+
* @param PaymentInterfaceFactory $paymentFactory
31+
* @param AdditionalDataProviderPool $paymentDataProvider
32+
*/
33+
public function __construct(
34+
PaymentInterfaceFactory $paymentFactory,
35+
AdditionalDataProviderPool $paymentDataProvider
36+
) {
37+
$this->paymentFactory = $paymentFactory;
38+
$this->paymentDataProvider = $paymentDataProvider;
39+
}
40+
41+
/**
42+
* Build a PaymentInterface object from the supplied data array
43+
*
44+
* @param array $paymentData
45+
* @return PaymentInterface
46+
* @throws GraphQlInputException
47+
*/
48+
public function build(array $paymentData): PaymentInterface
49+
{
50+
if (!isset($paymentData['code']) || empty($paymentData['code'])) {
51+
throw new GraphQlInputException(__('Required parameter "code" for "payment_method" is missing.'));
52+
}
53+
$paymentMethodCode = $paymentData['code'];
54+
55+
$poNumber = $paymentData['purchase_order_number'] ?? null;
56+
$additionalData = $this->paymentDataProvider->getData($paymentMethodCode, $paymentData);
57+
58+
return $this->paymentFactory->create(
59+
[
60+
'data' => [
61+
PaymentInterface::KEY_METHOD => $paymentMethodCode,
62+
PaymentInterface::KEY_PO_NUMBER => $poNumber,
63+
PaymentInterface::KEY_ADDITIONAL_DATA => $additionalData,
64+
],
65+
]
66+
);
67+
}
68+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Cart;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Quote\Api\CartManagementInterface;
13+
use Magento\Quote\Api\PaymentMethodManagementInterface;
14+
use Magento\Quote\Model\Quote;
15+
16+
/**
17+
* Place an order
18+
*/
19+
class PlaceOrder
20+
{
21+
/**
22+
* @var PaymentMethodManagementInterface
23+
*/
24+
private $paymentManagement;
25+
26+
/**
27+
* @var CartManagementInterface
28+
*/
29+
private $cartManagement;
30+
31+
/**
32+
* @param PaymentMethodManagementInterface $paymentManagement
33+
* @param CartManagementInterface $cartManagement
34+
*/
35+
public function __construct(
36+
PaymentMethodManagementInterface $paymentManagement,
37+
CartManagementInterface $cartManagement
38+
) {
39+
$this->paymentManagement = $paymentManagement;
40+
$this->cartManagement = $cartManagement;
41+
}
42+
43+
/**
44+
* Place an order
45+
*
46+
* @param Quote $cart
47+
* @param string $maskedCartId
48+
* @param int $userId
49+
* @return int
50+
*
51+
* @throws LocalizedException
52+
* @throws NoSuchEntityException
53+
*
54+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
55+
*/
56+
public function execute(Quote $cart, string $maskedCartId, int $userId): int
57+
{
58+
$cartId = (int)$cart->getId();
59+
$paymentMethod = $this->paymentManagement->get($cartId);
60+
61+
return (int)$this->cartManagement->placeOrder($cartId, $paymentMethod);
62+
}
63+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\QuoteGraphQl\Model\Cart;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\Exception\NoSuchEntityException;
12+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
13+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
14+
use Magento\Quote\Model\Quote;
15+
16+
/**
17+
* Set payment method and place order
18+
*/
19+
class SetPaymentAndPlaceOrder
20+
{
21+
/**
22+
* @var SetPaymentMethodOnCart
23+
*/
24+
private $setPaymentMethod;
25+
26+
/**
27+
* @var PlaceOrder
28+
*/
29+
private $placeOrder;
30+
31+
/**
32+
* @param SetPaymentMethodOnCart $setPaymentMethod
33+
* @param PlaceOrder $placeOrder
34+
*/
35+
public function __construct(
36+
SetPaymentMethodOnCart $setPaymentMethod,
37+
PlaceOrder $placeOrder
38+
) {
39+
$this->setPaymentMethod = $setPaymentMethod;
40+
$this->placeOrder = $placeOrder;
41+
}
42+
43+
/**
44+
* Set payment method and place order
45+
*
46+
* @param Quote $cart
47+
* @param string $maskedCartId
48+
* @param int $userId
49+
* @param array $paymentData
50+
* @return int
51+
*
52+
* @throws GraphQlInputException
53+
* @throws GraphQlNoSuchEntityException
54+
* @throws LocalizedException
55+
* @throws NoSuchEntityException
56+
*/
57+
public function execute(Quote $cart, string $maskedCartId, int $userId, array $paymentData): int
58+
{
59+
$this->setPaymentMethod->execute($cart, $paymentData);
60+
return $this->placeOrder->execute($cart, $maskedCartId, $userId);
61+
}
62+
}

0 commit comments

Comments
 (0)