Skip to content

Commit a8c459f

Browse files
committed
ACP2E-3376: refactoring based on CR
1 parent 57430a4 commit a8c459f

File tree

2 files changed

+171
-89
lines changed

2 files changed

+171
-89
lines changed

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

Lines changed: 8 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
1111
use Magento\Catalog\Model\ProductIdLocatorInterface;
1212
use Magento\Catalog\Model\ResourceModel\Attribute;
13+
use Magento\Catalog\Model\ResourceModel\Product\Price\BasePriceFactory;
1314
use Magento\Framework\App\ObjectManager;
1415
use Magento\Framework\EntityManager\MetadataPool;
1516
use Magento\Framework\Exception\CouldNotDeleteException;
@@ -88,14 +89,16 @@ class PricePersistence
8889
* @param MetadataPool $metadataPool
8990
* @param string $attributeCode
9091
* @param DateTime|null $dateTime
92+
* @param BasePriceFactory|null $basePriceFactory
9193
*/
9294
public function __construct(
9395
Attribute $attributeResource,
9496
ProductAttributeRepositoryInterface $attributeRepository,
9597
ProductIdLocatorInterface $productIdLocator,
9698
MetadataPool $metadataPool,
9799
$attributeCode = '',
98-
?DateTime $dateTime = null
100+
?DateTime $dateTime = null,
101+
private ?BasePriceFactory $basePriceFactory = null
99102
) {
100103
$this->attributeResource = $attributeResource;
101104
$this->attributeRepository = $attributeRepository;
@@ -104,6 +107,8 @@ public function __construct(
104107
$this->metadataPool = $metadataPool;
105108
$this->dateTime = $dateTime ?: ObjectManager::getInstance()
106109
->get(DateTime::class);
110+
$this->basePriceFactory = $this->basePriceFactory ?: ObjectManager::getInstance()
111+
->get(BasePriceFactory::class);
107112
}
108113

109114
/**
@@ -137,103 +142,17 @@ public function update(array $prices)
137142
return $price['attribute_id'] = (int)$this->getAttributeId();
138143
});
139144

140-
$connection = $this->attributeResource->getConnection();
141-
$connection->beginTransaction();
145+
$basePrice = $this->basePriceFactory->create(['attributeId' => (int)$this->getAttributeId()]);
142146
try {
143-
foreach (array_chunk($prices, $this->itemsPerOperation) as $pricesBunch) {
144-
$existingPrices = $this->getExistingPrices($pricesBunch);
145-
$pricesBunch = $this->doUpdate($pricesBunch, $existingPrices);
146-
$this->doInsert($pricesBunch);
147-
}
148-
$connection->commit();
147+
$basePrice->update($prices);
149148
} catch (\Exception $e) {
150-
$connection->rollBack();
151149
throw new CouldNotSaveException(
152150
__('Could not save Prices.'),
153151
$e
154152
);
155153
}
156154
}
157155

158-
/**
159-
* Get prices that will need update
160-
*
161-
* @param array $priceBunch
162-
* @return array
163-
*/
164-
private function getExistingPrices(array $priceBunch): array
165-
{
166-
$linkField = $this->getEntityLinkField();
167-
$connection = $this->attributeResource->getConnection();
168-
169-
return $connection->fetchAll(
170-
$connection->select()
171-
->from($this->attributeResource->getTable($this->table))
172-
->where('attribute_id = ?', $this->getAttributeId())
173-
->where('store_id IN (?)', array_unique(array_column($priceBunch, 'store_id')))
174-
->where($linkField . ' IN (?)', array_unique(array_column($priceBunch, $linkField)))
175-
);
176-
}
177-
178-
/**
179-
* Update existing prices
180-
*
181-
* @param array $priceBunches
182-
* @param array $existingPrices
183-
* @return array
184-
*/
185-
private function doUpdate(array $priceBunches, array $existingPrices): array
186-
{
187-
$updateData = [];
188-
$linkField = $this->getEntityLinkField();
189-
foreach ($existingPrices as $existingPrice) {
190-
foreach ($priceBunches as $key => $price) {
191-
if ($price[$linkField] == $existingPrice[$linkField] &&
192-
$price['store_id'] == $existingPrice['store_id'] &&
193-
$existingPrice['attribute_id'] == $price['attribute_id']
194-
) {
195-
$priceBunches[$key]['value_id'] = $existingPrice['value_id'];
196-
$uniqueKey = $price[$linkField].$price['attribute_id'].$price['store_id'];
197-
$updateData[$uniqueKey] = $priceBunches[$key];
198-
}
199-
}
200-
}
201-
if (!empty($updateData)) {
202-
foreach ($updateData as $row) {
203-
$this->attributeResource->getConnection()->update(
204-
$this->attributeResource->getTable($this->table),
205-
['value' => $row['value']],
206-
['value_id = ?' => (int)$row['value_id']]
207-
);
208-
}
209-
}
210-
return $priceBunches;
211-
}
212-
213-
/**
214-
* Insert new prices
215-
*
216-
* @param array $priceBunches
217-
* @return void
218-
*/
219-
private function doInsert(array $priceBunches): void
220-
{
221-
$insertData = [];
222-
$linkField = $this->getEntityLinkField();
223-
foreach ($priceBunches as $price) {
224-
if (!isset($price['value_id'])) {
225-
$uniqueKey = $price[$linkField].$price['attribute_id'].$price['store_id'];
226-
$insertData[$uniqueKey] = $price;
227-
}
228-
}
229-
if (!empty($insertData)) {
230-
$this->attributeResource->getConnection()->insertMultiple(
231-
$this->attributeResource->getTable($this->table),
232-
$insertData
233-
);
234-
}
235-
}
236-
237156
/**
238157
* Delete product attribute by SKU.
239158
*
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Model\ResourceModel\Product\Price;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Model\ResourceModel\Attribute;
12+
use Magento\Framework\DataObject;
13+
use Magento\Framework\EntityManager\MetadataPool;
14+
use Magento\Framework\Exception\CouldNotSaveException;
15+
16+
class BasePrice
17+
{
18+
/**
19+
* Price storage table.
20+
*
21+
* @var string
22+
*/
23+
private $table = 'catalog_product_entity_decimal';
24+
25+
/**
26+
* @param Attribute $attributeResource
27+
* @param MetadataPool $metadataPool
28+
* @param int $attributeId
29+
*/
30+
public function __construct(
31+
private readonly Attribute $attributeResource,
32+
private readonly MetadataPool $metadataPool,
33+
private readonly int $attributeId = 0,
34+
) {
35+
}
36+
37+
/**
38+
* Get prices that will need update
39+
*
40+
* @param array $priceBunch
41+
* @return array
42+
* @throws \Exception
43+
*/
44+
private function getExistingPrices(array $priceBunch): array
45+
{
46+
$linkField = $this->getEntityLinkField();
47+
$connection = $this->attributeResource->getConnection();
48+
49+
return $connection->fetchAll(
50+
$connection->select()
51+
->from($this->attributeResource->getTable($this->table))
52+
->where('attribute_id = ?', $this->attributeId)
53+
->where('store_id IN (?)', array_unique(array_column($priceBunch, 'store_id')))
54+
->where($linkField . ' IN (?)', array_unique(array_column($priceBunch, $linkField)))
55+
);
56+
}
57+
58+
/**
59+
* Get prices that will need update
60+
*
61+
* @param DataObject $priceBunchesObject
62+
* @param array $existingPrices
63+
* @return array
64+
* @throws \Exception
65+
*/
66+
private function getUpdatablePrices(DataObject $priceBunchesObject, array $existingPrices): array
67+
{
68+
$updateData = [];
69+
$priceBunches = $priceBunchesObject->getPrices();
70+
$linkField = $this->getEntityLinkField();
71+
foreach ($existingPrices as $existingPrice) {
72+
foreach ($priceBunches as $key => $price) {
73+
if ($price[$linkField] == $existingPrice[$linkField] &&
74+
$price['store_id'] == $existingPrice['store_id'] &&
75+
$existingPrice['attribute_id'] == $price['attribute_id']
76+
) {
77+
$priceBunches[$key]['value_id'] = $existingPrice['value_id'];
78+
$uniqueKey = $price[$linkField].'_'.$price['attribute_id'].'_'.$price['store_id'];
79+
$updateData[$uniqueKey] = $priceBunches[$key];
80+
}
81+
}
82+
}
83+
84+
$priceBunchesObject->setPrices($priceBunches);
85+
86+
return $updateData;
87+
}
88+
89+
/**
90+
* Get prices that will need insert
91+
*
92+
* @param DataObject $priceBunchesObject
93+
* @return array
94+
* @throws \Exception
95+
*/
96+
private function getInsertablePrices(DataObject $priceBunchesObject): array
97+
{
98+
$insertData = [];
99+
$priceBunches = $priceBunchesObject->getPrices();
100+
$linkField = $this->getEntityLinkField();
101+
foreach ($priceBunches as $price) {
102+
if (!isset($price['value_id'])) {
103+
$uniqueKey = $price[$linkField].'_'.$price['attribute_id'].'_'.$price['store_id'];
104+
$insertData[$uniqueKey] = $price;
105+
}
106+
}
107+
return $insertData;
108+
}
109+
110+
/**
111+
* Update existing prices
112+
*
113+
* @param array $priceBunches
114+
* @return void
115+
* @throws \Exception
116+
*/
117+
public function update(array $priceBunches): void
118+
{
119+
$priceBunchesObject = new DataObject(['prices' => $priceBunches]);
120+
$existingPrices = $this->getExistingPrices($priceBunches);
121+
$updateData = $this->getUpdatablePrices($priceBunchesObject, $existingPrices);
122+
$insertData = $this->getInsertablePrices($priceBunchesObject);
123+
124+
$connection = $this->attributeResource->getConnection();
125+
$connection->beginTransaction();
126+
try {
127+
if (!empty($updateData)) {
128+
foreach ($updateData as $row) {
129+
$this->attributeResource->getConnection()->update(
130+
$this->attributeResource->getTable($this->table),
131+
['value' => $row['value']],
132+
['value_id = ?' => (int)$row['value_id']]
133+
);
134+
}
135+
}
136+
if (!empty($insertData)) {
137+
$this->attributeResource->getConnection()->insertMultiple(
138+
$this->attributeResource->getTable($this->table),
139+
$insertData
140+
);
141+
}
142+
$connection->commit();
143+
} catch (\Exception $e) {
144+
$connection->rollBack();
145+
throw new CouldNotSaveException(
146+
__('Could not save Prices.'),
147+
$e
148+
);
149+
}
150+
}
151+
152+
/**
153+
* Get link field
154+
*
155+
* @return string
156+
* @throws \Exception
157+
*/
158+
private function getEntityLinkField(): string
159+
{
160+
return $this->metadataPool->getMetadata(ProductInterface::class)
161+
->getLinkField();
162+
}
163+
}

0 commit comments

Comments
 (0)