Skip to content

Commit 6c45e1a

Browse files
authored
LYNX-524 - Add customer information to CustomerOrder type
1 parent a4a0616 commit 6c45e1a

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*
6+
* NOTICE: All information contained herein is, and remains
7+
* the property of Adobe and its suppliers, if any. The intellectual
8+
* and technical concepts contained herein are proprietary to Adobe
9+
* and its suppliers and are protected by all applicable intellectual
10+
* property laws, including trade secret and copyright laws.
11+
* Dissemination of this information or reproduction of this material
12+
* is strictly forbidden unless prior written permission is obtained from
13+
* Adobe.
14+
*/
15+
declare(strict_types=1);
16+
17+
namespace Magento\SalesGraphQl\Model\Resolver;
18+
19+
use Magento\Framework\Exception\LocalizedException;
20+
use Magento\Framework\GraphQl\Config\Element\Field;
21+
use Magento\Framework\GraphQl\Query\ResolverInterface;
22+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
23+
use Magento\Sales\Model\Order;
24+
25+
class OrderCustomerInfo implements ResolverInterface
26+
{
27+
/**
28+
* @inheritDoc
29+
*/
30+
public function resolve(
31+
Field $field,
32+
$context,
33+
ResolveInfo $info,
34+
array $value = null,
35+
array $args = null
36+
): array {
37+
if (!isset($value['model']) || !($value['model'] instanceof Order)) {
38+
throw new LocalizedException(__('"model" value should be specified'));
39+
}
40+
41+
$order = $value['model'];
42+
43+
return [
44+
"firstname" => $order->getCustomerFirstname(),
45+
"lastname" => $order->getCustomerLastname() ?? null,
46+
"middlename" => $order->getCustomerMiddlename() ?? null,
47+
"prefix" => $order->getCustomerPrefix() ?? null,
48+
"suffix" => $order->getCustomerSuffix() ?? null
49+
];
50+
}
51+
}

app/code/Magento/SalesGraphQl/etc/schema.graphqls

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ type CustomerOrder @doc(description: "Contains details about each of the custome
8181
email: String @doc(description: "Order customer email.")
8282
is_virtual: Boolean! @doc(description: "`TRUE` if the order is virtual") @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\OrderIsVirtual")
8383
available_actions: [OrderActionType!]! @doc(description: "List of available order actions.") @resolver(class: "\\Magento\\SalesGraphQl\\Model\\Resolver\\OrderAvailableActions")
84+
customer_info: OrderCustomerInfo! @doc(description: "Returns customer information from order.") @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\OrderCustomerInfo")
85+
}
86+
87+
type OrderCustomerInfo {
88+
firstname: String! @doc(description: "First name of the customer")
89+
lastname: String @doc(description: "Last name of the customer")
90+
middlename: String @doc(description: "Middle name of the customer")
91+
prefix: String @doc(description: "Prefix of the customer")
92+
suffix: String @doc(description: "Suffix of the customer")
8493
}
8594

8695
type OrderAddress @doc(description: "Contains detailed information about an order's billing and shipping addresses."){
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
/************************************************************************
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*
6+
* NOTICE: All information contained herein is, and remains
7+
* the property of Adobe and its suppliers, if any. The intellectual
8+
* and technical concepts contained herein are proprietary to Adobe
9+
* and its suppliers and are protected by all applicable intellectual
10+
* property laws, including trade secret and copyright laws.
11+
* Dissemination of this information or reproduction of this material
12+
* is strictly forbidden unless prior written permission is obtained
13+
* from Adobe.
14+
* ************************************************************************
15+
*/
16+
declare(strict_types=1);
17+
18+
namespace Magento\GraphQl\Sales;
19+
20+
use Exception;
21+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
22+
use Magento\Checkout\Test\Fixture\PlaceOrder as PlaceOrderFixture;
23+
use Magento\Checkout\Test\Fixture\SetBillingAddress as SetBillingAddressFixture;
24+
use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethodFixture;
25+
use Magento\Customer\Test\Fixture\Customer as CustomerFixture;
26+
use Magento\Framework\Exception\AuthenticationException;
27+
use Magento\Framework\Exception\EmailNotConfirmedException;
28+
use Magento\Framework\Exception\LocalizedException;
29+
use Magento\Integration\Api\CustomerTokenServiceInterface;
30+
use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture;
31+
use Magento\Quote\Test\Fixture\CustomerCart as CustomerCartFixture;
32+
use Magento\TestFramework\Fixture\DataFixture;
33+
use Magento\TestFramework\Fixture\DataFixtureStorage;
34+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
35+
use Magento\TestFramework\Helper\Bootstrap;
36+
use Magento\TestFramework\TestCase\GraphQlAbstract;
37+
38+
/**
39+
* Test for orders.items.customer_info
40+
*/
41+
class OrderCustomerInfoTest extends GraphQlAbstract
42+
{
43+
/**
44+
* @var CustomerTokenServiceInterface
45+
*/
46+
private $customerTokenService;
47+
48+
/**
49+
* @var DataFixtureStorage
50+
*/
51+
private $fixtures;
52+
53+
/**
54+
* @return void
55+
* @throws LocalizedException
56+
*/
57+
protected function setUp(): void
58+
{
59+
parent::setUp();
60+
$this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
61+
$this->fixtures = Bootstrap::getObjectManager()->get(DataFixtureStorageManager::class)->getStorage();
62+
}
63+
64+
/**
65+
* Test the OrderCustomerInfo data for customerOrders query
66+
*
67+
* @throws AuthenticationException
68+
* @throws Exception
69+
*/
70+
#[
71+
DataFixture(ProductFixture::class, ['type_id' => 'virtual'], as: 'product'),
72+
DataFixture(
73+
CustomerFixture::class,
74+
[
75+
'firstname' => 'First Name',
76+
'lastname' => 'Last Name',
77+
'middlename' => 'Middle Name',
78+
'prefix' => 'MR'
79+
],
80+
as: 'customer'
81+
),
82+
DataFixture(CustomerCartFixture::class, ['customer_id' => '$customer.id$'], as: 'quote'),
83+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$quote.id$', 'product_id' => '$product.id$']),
84+
DataFixture(SetBillingAddressFixture::class, ['cart_id' => '$quote.id$']),
85+
DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$quote.id$']),
86+
DataFixture(
87+
PlaceOrderFixture::class,
88+
[
89+
'cart_id' => '$quote.id$',
90+
],
91+
'order1'
92+
),
93+
]
94+
public function testOrderCustomerInfoField()
95+
{
96+
$query = $this->getCustomerOrdersQuery();
97+
$customerEmail = $this->fixtures->get('customer')->getEmail();
98+
$response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($customerEmail, 'password'));
99+
$data = $response['customer']['orders']['items'];
100+
$firstItem = $data[0];
101+
$expected = [
102+
'firstname' => 'First Name',
103+
'lastname' => 'Last Name',
104+
'prefix' => 'MR',
105+
'middlename' => 'Middle Name',
106+
'suffix' => null
107+
];
108+
self::assertEquals($expected, $firstItem['customer_info']);
109+
}
110+
111+
/**
112+
* Get Customer Orders query with customerInfo field
113+
*
114+
* @return string
115+
*/
116+
private function getCustomerOrdersQuery(): string
117+
{
118+
return <<<QUERY
119+
query {
120+
customer {
121+
orders(pageSize: 10) {
122+
total_count
123+
items {
124+
customer_info {
125+
firstname
126+
lastname
127+
middlename
128+
prefix
129+
suffix
130+
}
131+
}
132+
}
133+
}
134+
}
135+
QUERY;
136+
}
137+
138+
/**
139+
* Returns the header with customer token for GQL Mutation
140+
*
141+
* @param string $email
142+
* @param string $password
143+
* @return array
144+
* @throws AuthenticationException
145+
* @throws EmailNotConfirmedException
146+
*/
147+
private function getCustomerAuthHeaders(string $email, string $password): array
148+
{
149+
$customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password);
150+
return ['Authorization' => 'Bearer ' . $customerToken];
151+
}
152+
}

0 commit comments

Comments
 (0)