Skip to content

Commit ada9c5e

Browse files
committed
Merge remote-tracking branch 'adobe-commerce-tier-4/ACP2E-2837' into Tier4-Kings-PR-03-05-2024
2 parents eb640a9 + eb88d3f commit ada9c5e

File tree

3 files changed

+115
-9
lines changed

3 files changed

+115
-9
lines changed

app/code/Magento/Catalog/Model/Product/Price/BasePriceStorage.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,11 @@ public function update(array $prices)
157157
{
158158
$prices = $this->retrieveValidPrices($prices);
159159
$formattedPrices = [];
160+
$productIds = [];
160161

161162
foreach ($prices as $price) {
162163
$ids = array_keys($this->productIdLocator->retrieveProductIdsBySkus([$price->getSku()])[$price->getSku()]);
164+
$productIds[] = $ids[key($ids)];
163165
foreach ($ids as $id) {
164166
$formattedPrices[] = [
165167
'store_id' => $price->getStoreId(),
@@ -182,6 +184,7 @@ public function update(array $prices)
182184
}
183185

184186
$this->getPricePersistence()->update($formattedPrices);
187+
$this->getPricePersistence()->updateLastUpdatedAt($productIds);
185188

186189
return $this->validationResult->getFailedItems();
187190
}

app/code/Magento/Catalog/Model/Product/Price/PricePersistence.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
1111
use Magento\Catalog\Model\ProductIdLocatorInterface;
1212
use Magento\Catalog\Model\ResourceModel\Attribute;
13+
use Magento\Framework\App\ObjectManager;
1314
use Magento\Framework\EntityManager\MetadataPool;
1415
use Magento\Framework\Exception\CouldNotDeleteException;
1516
use Magento\Framework\Exception\CouldNotSaveException;
17+
use Magento\Framework\Stdlib\DateTime\DateTime;
1618

1719
/**
1820
* Class responsibly for persistence of prices.
21+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1922
*/
2023
class PricePersistence
2124
{
@@ -42,33 +45,40 @@ class PricePersistence
4245
private $productIdLocator;
4346

4447
/**
45-
* Metadata pool.
48+
* Metadata pool property to get a metadata.
4649
*
4750
* @var MetadataPool
4851
*/
4952
private $metadataPool;
5053

5154
/**
52-
* Attribute code.
55+
* Attribute code attribute to get the attribute id.
5356
*
5457
* @var string
5558
*/
5659
private $attributeCode;
5760

5861
/**
59-
* Attribute ID.
62+
* Attribute ID property to store the attribute id.
6063
*
6164
* @var int
6265
*/
6366
private $attributeId;
6467

6568
/**
66-
* Items per operation.
69+
* Items per operation to chunk the array in a batch.
6770
*
6871
* @var int
6972
*/
7073
private $itemsPerOperation = 500;
7174

75+
/**
76+
* Date time property to get the gm date.
77+
*
78+
* @var DateTime
79+
*/
80+
private $dateTime;
81+
7282
/**
7383
* PricePersistence constructor.
7484
*
@@ -77,19 +87,23 @@ class PricePersistence
7787
* @param ProductIdLocatorInterface $productIdLocator
7888
* @param MetadataPool $metadataPool
7989
* @param string $attributeCode
90+
* @param DateTime|null $dateTime
8091
*/
8192
public function __construct(
8293
Attribute $attributeResource,
8394
ProductAttributeRepositoryInterface $attributeRepository,
8495
ProductIdLocatorInterface $productIdLocator,
8596
MetadataPool $metadataPool,
86-
$attributeCode = ''
97+
$attributeCode = '',
98+
?DateTime $dateTime = null
8799
) {
88100
$this->attributeResource = $attributeResource;
89101
$this->attributeRepository = $attributeRepository;
90102
$this->attributeCode = $attributeCode;
91103
$this->productIdLocator = $productIdLocator;
92104
$this->metadataPool = $metadataPool;
105+
$this->dateTime = $dateTime ?: ObjectManager::getInstance()
106+
->get(DateTime::class);
93107
}
94108

95109
/**
@@ -233,4 +247,27 @@ public function getEntityLinkField()
233247
return $this->metadataPool->getMetadata(ProductInterface::class)
234248
->getLinkField();
235249
}
250+
251+
/**
252+
* Update last updated date.
253+
*
254+
* @param array $productIds
255+
* @return void
256+
* @throws CouldNotSaveException
257+
*/
258+
public function updateLastUpdatedAt(array $productIds): void
259+
{
260+
try {
261+
$this->attributeResource->getConnection()->update(
262+
$this->attributeResource->getTable('catalog_product_entity'),
263+
[ProductInterface::UPDATED_AT => $this->dateTime->gmtDate()],
264+
[$this->getEntityLinkField(). ' IN(?)' => $productIds]
265+
);
266+
} catch (\Exception $e) {
267+
throw new CouldNotSaveException(
268+
__("The attribute can't be saved."),
269+
$e
270+
);
271+
}
272+
}
236273
}

dev/tests/api-functional/testsuite/Magento/Catalog/Api/BasePriceStorageTest.php

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,48 @@
66

77
namespace Magento\Catalog\Api;
88

9+
use Magento\Catalog\Model\ProductRepository;
10+
use Magento\TestFramework\Helper\Bootstrap;
911
use Magento\TestFramework\TestCase\WebapiAbstract;
1012
use Magento\Framework\Webapi\Exception as HTTPExceptionCodes;
13+
use Magento\Catalog\Model\ProductRepositoryFactory;
14+
use Magento\TestFramework\Fixture\DataFixture;
15+
use Magento\TestFramework\Fixture\DataFixtureStorage;
16+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
17+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1118

1219
/**
13-
* BasePriceStorage test.
20+
* Base price storage test to test the update and update with invalid parameter.
1421
*/
1522
class BasePriceStorageTest extends WebapiAbstract
1623
{
17-
const SERVICE_NAME = 'catalogBasePriceStorageV1';
18-
const SERVICE_VERSION = 'V1';
19-
const SIMPLE_PRODUCT_SKU = 'simple';
24+
private const SERVICE_NAME = 'catalogBasePriceStorageV1';
25+
private const SERVICE_VERSION = 'V1';
26+
private const SIMPLE_PRODUCT_SKU = 'simple';
2027

2128
/**
2229
* @var \Magento\TestFramework\ObjectManager
2330
*/
2431
private $objectManager;
2532

33+
/**
34+
* @var ProductRepositoryFactory
35+
*/
36+
private $repositoryFactory;
37+
38+
/**
39+
* @var DataFixtureStorage
40+
*/
41+
private $fixtures;
42+
2643
/**
2744
* Set up.
2845
*/
2946
protected function setUp(): void
3047
{
3148
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
49+
$this->repositoryFactory = Bootstrap::getObjectManager()->get(ProductRepositoryFactory::class);
50+
$this->fixtures = $this->objectManager->get(DataFixtureStorageManager::class)->getStorage();
3251
}
3352

3453
/**
@@ -157,4 +176,51 @@ public function testUpdateWithInvalidParameters()
157176

158177
$this->assertEquals($expectedResponse, $response);
159178
}
179+
180+
/**
181+
* Test update last updated at method.
182+
*
183+
*/
184+
#[
185+
DataFixture(ProductFixture::class, as: 'product'),
186+
]
187+
public function testUpdateLastUpdatedAt()
188+
{
189+
$product = $this->fixtures->get('product');
190+
$productSku = $product->getSku();
191+
/** @var ProductRepository $beforeProductRepository */
192+
$beforeProductRepository = $this->repositoryFactory->create();
193+
$beforeProductUpdatedAt = $beforeProductRepository->get($productSku)->getUpdatedAt();
194+
$serviceInfo = [
195+
'rest' => [
196+
'resourcePath' => '/V1/products/base-prices',
197+
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST
198+
],
199+
'soap' => [
200+
'service' => self::SERVICE_NAME,
201+
'serviceVersion' => self::SERVICE_VERSION,
202+
'operation' => self::SERVICE_NAME . 'Update',
203+
],
204+
];
205+
$newPrice = 9999;
206+
$storeId = 0;
207+
$response = $this->_webApiCall(
208+
$serviceInfo,
209+
[
210+
'prices' => [
211+
[
212+
'price' => $newPrice,
213+
'store_id' => $storeId,
214+
'sku' => $productSku,
215+
]
216+
]
217+
]
218+
);
219+
$this->assertEmpty($response);
220+
221+
/** @var ProductRepository $afterProductRepository */
222+
$afterProductRepository = $this->repositoryFactory->create();
223+
$afterProductUpdatedAt = $afterProductRepository->get($productSku)->getUpdatedAt();
224+
$this->assertTrue(strtotime($afterProductUpdatedAt) >= strtotime($beforeProductUpdatedAt));
225+
}
160226
}

0 commit comments

Comments
 (0)