Skip to content

Commit 89b968a

Browse files
committed
#26121: special price & tier price are coming in base currency
Edits, Support by api-functional tests, Address static tests
1 parent cce0a99 commit 89b968a

File tree

5 files changed

+348
-20
lines changed

5 files changed

+348
-20
lines changed

app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
1111
use Magento\Catalog\Model\ResourceModel\Product\Collection;
1212
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
13-
use Magento\CatalogCustomerGraphQl\Pricing\Price\TierPrice;
1413
use Magento\Customer\Model\GroupManagement;
1514
use Magento\Catalog\Api\Data\ProductTierPriceInterface;
1615
use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool;
17-
use Magento\Framework\App\ObjectManager;
1816
use Magento\Catalog\Model\Product\Type\Price;
17+
use Magento\CatalogCustomerGraphQl\Pricing\Price\TierPriceFactory;
1918

2019
/**
2120
* Get product tier price information
@@ -62,25 +61,33 @@ class Tiers
6261
*/
6362
private $price;
6463

64+
/**
65+
* @var TierPriceFactory
66+
*/
67+
private $tierPriceFactory;
68+
6569
/**
6670
* @param CollectionFactory $collectionFactory
6771
* @param ProductResource $productResource
6872
* @param PriceProviderPool $priceProviderPool
6973
* @param int $customerGroupId
7074
* @param Price $price
75+
* @param TierPriceFactory $tierPriceFactory
7176
*/
7277
public function __construct(
7378
CollectionFactory $collectionFactory,
7479
ProductResource $productResource,
7580
PriceProviderPool $priceProviderPool,
7681
$customerGroupId,
77-
Price $price
82+
Price $price,
83+
TierPriceFactory $tierPriceFactory
7884
) {
7985
$this->collectionFactory = $collectionFactory;
8086
$this->productResource = $productResource;
8187
$this->priceProviderPool = $priceProviderPool;
8288
$this->customerGroupId = $customerGroupId;
8389
$this->price = $price;
90+
$this->tierPriceFactory = $tierPriceFactory;
8491
}
8592

8693
/**
@@ -110,7 +117,7 @@ public function getProductTierPrices($productId): ?array
110117
}
111118

112119
/** @var TierPrice $tierPrice */
113-
$tierPrice = ObjectManager::getInstance()->create(TierPrice::class,
120+
$tierPrice = $this->tierPriceFactory->create(
114121
[
115122
'saleableItem' => $this->products[$productId],
116123
'quantity' => 1,

app/code/Magento/CatalogCustomerGraphQl/Pricing/Price/TierPrice.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
use Magento\Catalog\Model\Product;
1212
use Magento\Customer\Api\GroupManagementInterface;
13-
use Magento\Customer\Model\Session;
1413
use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
1514
use Magento\Framework\Pricing\PriceCurrencyInterface;
15+
use Magento\Framework\App\ObjectManager;
1616

1717
class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice
1818
{
@@ -22,7 +22,6 @@ class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice
2222
* @param float $quantity
2323
* @param CalculatorInterface $calculator
2424
* @param PriceCurrencyInterface $priceCurrency
25-
* @param Session $customerSession
2625
* @param GroupManagementInterface $groupManagement
2726
* @param int $customerGroupId
2827
*/
@@ -31,7 +30,6 @@ public function __construct(
3130
$quantity,
3231
CalculatorInterface $calculator,
3332
PriceCurrencyInterface $priceCurrency,
34-
Session $customerSession,
3533
GroupManagementInterface $groupManagement,
3634
$customerGroupId
3735
) {
@@ -40,7 +38,7 @@ public function __construct(
4038
$quantity,
4139
$calculator,
4240
$priceCurrency,
43-
$customerSession,
41+
ObjectManager::getInstance()->get(\Magento\Customer\Model\Session::class),
4442
$groupManagement
4543
);
4644

app/code/Magento/CatalogGraphQl/Model/Resolver/Product/SpecialPrice.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,19 @@
88
namespace Magento\CatalogGraphQl\Model\Resolver\Product;
99

1010
use Magento\Framework\GraphQl\Config\Element\Field;
11-
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
12-
use Magento\Framework\GraphQl\Query\Resolver\Value;
1311
use Magento\Framework\GraphQl\Query\ResolverInterface;
1412
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1513
use Magento\Catalog\Pricing\Price\SpecialPrice as PricingSpecialPrice;
1614

15+
/**
16+
* Resolver for Special Price
17+
*/
1718
class SpecialPrice implements ResolverInterface
1819
{
1920
/**
20-
* Fetches the data from persistence models and format it according to the GraphQL schema.
21-
*
22-
* @param \Magento\Framework\GraphQl\Config\Element\Field $field
23-
* @param ContextInterface $context
24-
* @param ResolveInfo $info
25-
* @param array|null $value
26-
* @param array|null $args
27-
* @return mixed|Value
28-
* @throws \Exception
29-
*/public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
21+
* @inheritdoc
22+
*/
23+
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
3024
{
3125
/** @var \Magento\Catalog\Model\Product $product */
3226
$product = $value['model'];
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
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\GraphQl\CatalogCustomer;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Catalog\Model\Product;
14+
use Magento\Integration\Api\CustomerTokenServiceInterface;
15+
use Magento\TestFramework\TestCase\GraphQlAbstract;
16+
use Magento\Store\Api\StoreRepositoryInterface;
17+
use Magento\TestFramework\Helper\Bootstrap;
18+
19+
class PriceTiersTest extends GraphQlAbstract
20+
{
21+
/**
22+
* @var \Magento\TestFramework\ObjectManager
23+
*/
24+
private $objectManager;
25+
26+
protected function setUp(): void
27+
{
28+
$this->objectManager = Bootstrap::getObjectManager();
29+
}
30+
31+
/**
32+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
33+
*/
34+
public function testAllGroups()
35+
{
36+
/** @var string $productSku */
37+
$productSku = 'simple';
38+
/** @var string $query */
39+
$query = $this->getProductSearchQuery($productSku);
40+
41+
$response = $this->graphQlQuery($query);
42+
43+
$itemTiers = $response['products']['items'][0]['price_tiers'];
44+
$this->assertEquals(5, sizeof($itemTiers));
45+
$this->assertEquals(8, $this->getValueForQuantity(2, $itemTiers));
46+
$this->assertEquals(5, $this->getValueForQuantity(3, $itemTiers));
47+
$this->assertEquals(6, $this->getValueForQuantity(3.2, $itemTiers));
48+
}
49+
50+
/**
51+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
52+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
53+
*/
54+
public function testLoggedInCustomer()
55+
{
56+
/** @var string $productSku */
57+
$productSku = 'simple';
58+
/** @var ProductRepositoryInterface $productRepository */
59+
$productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
60+
/** @var Product $product */
61+
$product = $productRepository->get($productSku, false, null, true);
62+
$tierPriceData =[
63+
[
64+
'customer_group_id' => 1,
65+
'percentage_value'=> null,
66+
'qty'=> 2,
67+
'value'=> 9
68+
],
69+
[
70+
'customer_group_id' => 1,
71+
'percentage_value'=> null,
72+
'qty'=> 3,
73+
'value'=> 8.25
74+
],
75+
[
76+
'customer_group_id' => 1,
77+
'percentage_value'=> null,
78+
'qty'=> 5,
79+
'value'=> 7
80+
],
81+
[
82+
'customer_group_id' => 2,
83+
'percentage_value'=> null,
84+
'qty'=> 3,
85+
'value'=> 8
86+
]
87+
];
88+
89+
$this->saveTierPrices($product, $tierPriceData);
90+
/** @var string $query */
91+
92+
$query = $this->getProductSearchQuery($productSku);
93+
$response = $this->graphQlQuery(
94+
$query,
95+
[],
96+
'',
97+
$this->getHeaderAuthorization('[email protected]', 'password')
98+
);
99+
100+
$itemTiers = $response['products']['items'][0]['price_tiers'];
101+
$this->assertEquals(3, sizeof($itemTiers));
102+
$this->assertEquals(9, $this->getValueForQuantity(2, $itemTiers));
103+
$this->assertEquals(8.25, $this->getValueForQuantity(3, $itemTiers));
104+
$this->assertEquals(7, $this->getValueForQuantity(5, $itemTiers));
105+
}
106+
107+
/**
108+
* @magentoApiDataFixture Magento/Store/_files/second_store_with_second_currency.php
109+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
110+
* @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
111+
*/
112+
public function testSecondStoreViewWithCurrencyRate()
113+
{
114+
/** @var string $storeViewCode */
115+
$storeViewCode = 'fixture_second_store';
116+
/** @var StoreRepositoryInterface $storeRepository */
117+
$storeRepository = $this->objectManager->get(StoreRepositoryInterface::class);
118+
/** @var float $rate */
119+
$rate = $storeRepository->get($storeViewCode)->getCurrentCurrencyRate();
120+
/** @var string $productSku */
121+
$productSku = 'simple';
122+
/** @var string $query */
123+
$query = $this->getProductSearchQuery($productSku);
124+
/** @var array $headers */
125+
$headers = array_merge(
126+
$this->getHeaderAuthorization('[email protected]', 'password'),
127+
$this->getHeaderStore($storeViewCode)
128+
);
129+
130+
$response = $this->graphQlQuery(
131+
$query,
132+
[],
133+
'',
134+
$headers
135+
);
136+
137+
$itemTiers = $response['products']['items'][0]['price_tiers'];
138+
$this->assertEquals(2, sizeof($itemTiers));
139+
$this->assertEquals(round(8 * $rate, 2), $this->getValueForQuantity(2, $itemTiers));
140+
$this->assertEquals(round(5 * $rate, 2), $this->getValueForQuantity(5, $itemTiers));
141+
}
142+
143+
/**
144+
* @param float $quantity
145+
* @param array $tiers
146+
* @return float
147+
*/
148+
private function getValueForQuantity(float $quantity, array $tiers)
149+
{
150+
$filteredResult = array_values(array_filter($tiers, function($tier) use ($quantity) {
151+
if ((float)$tier['quantity'] == $quantity) {
152+
return $tier;
153+
}
154+
}));
155+
156+
return (float)$filteredResult[0]['final_price']['value'];
157+
}
158+
159+
/**
160+
* @param ProductInterface $product
161+
* @param array $tierPriceData
162+
*/
163+
private function saveTierPrices(ProductInterface $product, array $tierPriceData)
164+
{
165+
/** @var array $tierPrices */
166+
$tierPrices = [];
167+
/** @var ProductTierPriceInterfaceFactory $tierPriceFactory */
168+
$tierPriceFactory = $this->objectManager->get(ProductTierPriceInterfaceFactory::class);
169+
170+
foreach ($tierPriceData as $tierPrice) {
171+
$tierPrices[] = $tierPriceFactory->create(
172+
[
173+
'data' => $tierPrice
174+
]
175+
);
176+
}
177+
178+
$product->setTierPrices($tierPrices);
179+
$product->save();
180+
}
181+
182+
/**
183+
* @param string $productSku
184+
* @return string
185+
*/
186+
private function getProductSearchQuery(string $productSku): string
187+
{
188+
return <<<QUERY
189+
{
190+
products(search: "{$productSku}") {
191+
items {
192+
price_tiers {
193+
final_price {
194+
currency
195+
value
196+
}
197+
discount {
198+
amount_off
199+
percent_off
200+
}
201+
quantity
202+
}
203+
}
204+
}
205+
}
206+
QUERY;
207+
}
208+
209+
/**
210+
* @param string $username
211+
* @param string $password
212+
* @return array
213+
*/
214+
private function getHeaderAuthorization(string $username, string $password): array
215+
{
216+
$customerToken = $this->objectManager->get(CustomerTokenServiceInterface::class)
217+
->createCustomerAccessToken($username, $password);
218+
219+
return ['Authorization' => 'Bearer ' . $customerToken];
220+
}
221+
222+
/**
223+
* @param string $storeViewCode
224+
* @return array
225+
*/
226+
private function getHeaderStore(string $storeViewCode): array
227+
{
228+
return ['Store' => $storeViewCode];
229+
}
230+
}

0 commit comments

Comments
 (0)