6
6
7
7
namespace Magento \Catalog \Model \ResourceModel \Product \Price ;
8
8
9
+ use Magento \Catalog \Api \ProductAttributeRepositoryInterface ;
10
+ use Magento \Catalog \Api \SpecialPriceInterface ;
11
+ use Magento \Catalog \Helper \Data ;
12
+ use Magento \Catalog \Model \ProductIdLocatorInterface ;
13
+ use Magento \Catalog \Model \ResourceModel \Attribute ;
14
+ use Magento \Framework \EntityManager \MetadataPool ;
15
+ use Magento \Framework \Exception \CouldNotDeleteException ;
16
+ use Magento \Framework \App \ObjectManager ;
17
+
9
18
/**
10
19
* Special price resource.
11
20
*/
12
- class SpecialPrice implements \ Magento \ Catalog \ Api \ SpecialPriceInterface
21
+ class SpecialPrice implements SpecialPriceInterface
13
22
{
14
23
/**
15
24
* Price storage table.
@@ -26,24 +35,24 @@ class SpecialPrice implements \Magento\Catalog\Api\SpecialPriceInterface
26
35
private $ datetimeTable = 'catalog_product_entity_datetime ' ;
27
36
28
37
/**
29
- * @var \Magento\Catalog\Model\ResourceModel\ Attribute
38
+ * @var Attribute
30
39
*/
31
40
private $ attributeResource ;
32
41
33
42
/**
34
- * @var \Magento\Catalog\Api\ ProductAttributeRepositoryInterface
43
+ * @var ProductAttributeRepositoryInterface
35
44
*/
36
45
private $ attributeRepository ;
37
46
38
47
/**
39
- * @var \Magento\Catalog\Model\ ProductIdLocatorInterface
48
+ * @var ProductIdLocatorInterface
40
49
*/
41
50
private $ productIdLocator ;
42
51
43
52
/**
44
53
* Metadata pool.
45
54
*
46
- * @var \Magento\Framework\EntityManager\ MetadataPool
55
+ * @var MetadataPool
47
56
*/
48
57
private $ metadataPool ;
49
58
@@ -68,6 +77,11 @@ class SpecialPrice implements \Magento\Catalog\Api\SpecialPriceInterface
68
77
*/
69
78
private $ priceToAttributeId ;
70
79
80
+ /**
81
+ * @var Data
82
+ */
83
+ private $ catalogData ;
84
+
71
85
/**
72
86
* Items per operation.
73
87
*
@@ -76,25 +90,28 @@ class SpecialPrice implements \Magento\Catalog\Api\SpecialPriceInterface
76
90
private $ itemsPerOperation = 500 ;
77
91
78
92
/**
79
- * @param \Magento\Catalog\Model\ResourceModel\Attribute $attributeResource
80
- * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
81
- * @param \Magento\Catalog\Model\ProductIdLocatorInterface $productIdLocator
82
- * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
93
+ * @param Attribute $attributeResource
94
+ * @param ProductAttributeRepositoryInterface $attributeRepository
95
+ * @param ProductIdLocatorInterface $productIdLocator
96
+ * @param MetadataPool $metadataPool
97
+ * @param Data|null $catalogData
83
98
*/
84
99
public function __construct (
85
- \Magento \Catalog \Model \ResourceModel \Attribute $ attributeResource ,
86
- \Magento \Catalog \Api \ProductAttributeRepositoryInterface $ attributeRepository ,
87
- \Magento \Catalog \Model \ProductIdLocatorInterface $ productIdLocator ,
88
- \Magento \Framework \EntityManager \MetadataPool $ metadataPool
100
+ Attribute $ attributeResource ,
101
+ ProductAttributeRepositoryInterface $ attributeRepository ,
102
+ ProductIdLocatorInterface $ productIdLocator ,
103
+ MetadataPool $ metadataPool ,
104
+ ?Data $ catalogData = null
89
105
) {
90
106
$ this ->attributeResource = $ attributeResource ;
91
107
$ this ->attributeRepository = $ attributeRepository ;
92
108
$ this ->productIdLocator = $ productIdLocator ;
93
109
$ this ->metadataPool = $ metadataPool ;
110
+ $ this ->catalogData = $ catalogData ?: ObjectManager::getInstance ()->get (Data::class);
94
111
}
95
112
96
113
/**
97
- * { @inheritdoc}
114
+ * @inheritdoc
98
115
*/
99
116
public function get (array $ skus )
100
117
{
@@ -132,7 +149,7 @@ public function get(array $skus)
132
149
}
133
150
134
151
/**
135
- * { @inheritdoc}
152
+ * @inheritdoc
136
153
*/
137
154
public function update (array $ prices )
138
155
{
@@ -187,47 +204,69 @@ public function update(array $prices)
187
204
}
188
205
189
206
/**
190
- * { @inheritdoc}
207
+ * @inheritdoc
191
208
*/
192
209
public function delete (array $ prices )
193
210
{
194
- $ skus = array_unique (
195
- array_map (function ($ price ) {
196
- return $ price ->getSku ();
197
- }, $ prices )
198
- );
199
- $ ids = $ this ->retrieveAffectedIds ($ skus );
200
211
$ connection = $ this ->attributeResource ->getConnection ();
201
- $ connection ->beginTransaction ();
202
- try {
203
- foreach (array_chunk ($ ids , $ this ->itemsPerOperation ) as $ idsBunch ) {
204
- $ this ->attributeResource ->getConnection ()->delete (
205
- $ this ->attributeResource ->getTable ($ this ->priceTable ),
206
- [
207
- 'attribute_id = ? ' => $ this ->getPriceAttributeId (),
208
- $ this ->getEntityLinkField () . ' IN (?) ' => $ idsBunch
209
- ]
210
- );
212
+
213
+ foreach ($ this ->getStoreSkus ($ prices ) as $ storeId => $ skus ) {
214
+
215
+ $ ids = $ this ->retrieveAffectedIds (array_unique ($ skus ));
216
+ $ connection ->beginTransaction ();
217
+ try {
218
+ foreach (array_chunk ($ ids , $ this ->itemsPerOperation ) as $ idsBunch ) {
219
+ $ connection ->delete (
220
+ $ this ->attributeResource ->getTable ($ this ->priceTable ),
221
+ [
222
+ 'attribute_id = ? ' => $ this ->getPriceAttributeId (),
223
+ 'store_id = ? ' => $ storeId ,
224
+ $ this ->getEntityLinkField () . ' IN (?) ' => $ idsBunch
225
+ ]
226
+ );
227
+ }
228
+ foreach (array_chunk ($ ids , $ this ->itemsPerOperation ) as $ idsBunch ) {
229
+ $ connection ->delete (
230
+ $ this ->attributeResource ->getTable ($ this ->datetimeTable ),
231
+ [
232
+ 'attribute_id IN (?) ' => [$ this ->getPriceFromAttributeId (), $ this ->getPriceToAttributeId ()],
233
+ 'store_id = ? ' => $ storeId ,
234
+ $ this ->getEntityLinkField () . ' IN (?) ' => $ idsBunch
235
+ ]
236
+ );
237
+ }
238
+ $ connection ->commit ();
239
+ } catch (\Exception $ e ) {
240
+ $ connection ->rollBack ();
241
+ throw new CouldNotDeleteException (__ ('Could not delete Prices ' ), $ e );
211
242
}
212
- foreach (array_chunk ($ ids , $ this ->itemsPerOperation ) as $ idsBunch ) {
213
- $ this ->attributeResource ->getConnection ()->delete (
214
- $ this ->attributeResource ->getTable ($ this ->datetimeTable ),
215
- [
216
- 'attribute_id IN (?) ' => [$ this ->getPriceFromAttributeId (), $ this ->getPriceToAttributeId ()],
217
- $ this ->getEntityLinkField () . ' IN (?) ' => $ idsBunch
218
- ]
243
+ }
244
+
245
+ return true ;
246
+ }
247
+
248
+ /**
249
+ * Returns associative arrays of store_id as key and array of skus as value.
250
+ *
251
+ * @param \Magento\Catalog\Api\Data\SpecialPriceInterface[] $priceItems
252
+ * @return array
253
+ * @throws CouldNotDeleteException
254
+ */
255
+ private function getStoreSkus (array $ priceItems ): array
256
+ {
257
+ $ isPriceGlobal = $ this ->catalogData ->isPriceGlobal ();
258
+
259
+ $ storeSkus = [];
260
+ foreach ($ priceItems as $ priceItem ) {
261
+ if ($ isPriceGlobal && $ priceItem ->getStoreId () !== 0 ) {
262
+ throw new CouldNotDeleteException (
263
+ __ ('Could not delete Prices for non-default store when price scope is global. ' )
219
264
);
220
265
}
221
- $ connection ->commit ();
222
- } catch (\Exception $ e ) {
223
- $ connection ->rollBack ();
224
- throw new \Magento \Framework \Exception \CouldNotDeleteException (
225
- __ ('Could not delete Prices ' ),
226
- $ e
227
- );
266
+ $ storeSkus [$ priceItem ->getStoreId ()][] = $ priceItem ->getSku ();
228
267
}
229
268
230
- return true ;
269
+ return $ storeSkus ;
231
270
}
232
271
233
272
/**
@@ -312,9 +351,9 @@ private function retrieveAffectedIds(array $skus)
312
351
$ affectedIds = [];
313
352
314
353
foreach ($ this ->productIdLocator ->retrieveProductIdsBySkus ($ skus ) as $ productIds ) {
315
- $ affectedIds = array_merge ( $ affectedIds , array_keys ($ productIds) );
354
+ $ affectedIds[] = array_keys ($ productIds );
316
355
}
317
356
318
- return array_unique ($ affectedIds );
357
+ return array_unique (array_merge ([], ... $ affectedIds) );
319
358
}
320
359
}
0 commit comments